-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.htaccess
More file actions
180 lines (147 loc) · 5.41 KB
/
Copy path.htaccess
File metadata and controls
180 lines (147 loc) · 5.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# /*
# * SPDX-License-Identifier: AGPL-3.0-or-later
# * SPDX-FileCopyrightText: Copyright 2026 Siemens Healthineers
# */
# Device Assessment and Vulnerability Exposure (DAVE) - Apache Configuration
# URL rewriting and security configuration
# Enable rewrite engine
RewriteEngine On
# Disable directory slash redirect - THIS IS CRITICAL for POST requests
# Without this, Apache will redirect /api/v1/assets -> /api/v1/assets/ (POST becomes GET)
DirectorySlash Off
# CORS Headers - Allow all origins for API access
<IfModule mod_headers.c>
# Always set CORS headers for all requests (including OPTIONS)
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, PATCH, OPTIONS"
Header always set Access-Control-Allow-Headers "Content-Type, Authorization, X-API-Key, X-Requested-With"
Header always set Access-Control-Max-Age "86400"
Header always set Access-Control-Expose-Headers "Content-Length, Content-Type"
# Private Network Access (PNA) - Allow public sites to access localhost
# This allows testing from online Swagger editors
Header always set Access-Control-Allow-Private-Network "true"
</IfModule>
# Handle OPTIONS preflight requests - respond with 204 No Content
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ - [R=204,L]
</IfModule>
# Security headers
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Force HTTPS (uncomment in production)
# RewriteCond %{HTTPS} off
# RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Redirect root to index.php
DirectoryIndex index.php index.html
# Handle API routes - MUST come before directory checks
# Route API subpaths via query string instead of PATH_INFO to avoid
# Apache path-info handling differences that can cause nested route 404s.
RewriteRule ^api/v1/?(.*)$ /api/v1/index.php?path=$1 [QSA,END]
# Handle page routes - pass through if file exists
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^pages/(.*)$ - [L]
# Handle asset routes - pass through if file exists
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^assets/(.*)$ - [L]
# Handle download routes - pass through if file exists in uploads
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^downloads/(.*)$ - [L]
# Handle documentation routes - pass through if file exists
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^docs/(.*)$ - [L]
# Default route - redirect to index.php
RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteCond %{REQUEST_URI} !^/api/
RewriteCond %{REQUEST_URI} !^/pages/
RewriteCond %{REQUEST_URI} !^/assets/
RewriteCond %{REQUEST_URI} !^/docs/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php [QSA,L]
# Security: Deny access to sensitive files
<Files "*.php">
<RequireAll>
Require all granted
</RequireAll>
</Files>
<Files "*.sql">
Require all denied
</Files>
<Files "*.log">
Require all denied
</Files>
<Files ".htaccess">
Require all denied
</Files>
<Files "*.env">
Require all denied
</Files>
<Files "*.config">
Require all denied
</Files>
# Deny access to config directory
RewriteRule ^config/ - [F,L]
# Deny access to logs directory
RewriteRule ^logs/ - [F,L]
# Deny access to temp directory
RewriteRule ^temp/ - [F,L]
# Deny access to cache directory
RewriteRule ^cache/ - [F,L]
# Deny access to includes directory
RewriteRule ^includes/ - [F,L]
# Cache control for static assets
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
</IfModule>
# Compression for better performance
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/json
</IfModule>
# Error pages
ErrorDocument 404 /pages/404.php
ErrorDocument 403 /pages/403.php
ErrorDocument 500 /pages/500.php
# PHP settings
<IfModule mod_php8.c>
php_value upload_max_filesize 50M
php_value post_max_size 50M
php_value max_execution_time 300
php_value max_input_time 300
php_value memory_limit 256M
</IfModule>
# Disable server signature
ServerSignature Off
# Disable directory browsing
Options -Indexes
# Prevent access to backup files
<FilesMatch "\.(bak|backup|old|orig|save|swp|tmp)$">
Require all denied
</FilesMatch>
# Prevent access to version control files
<FilesMatch "\.(git|svn|hg)">
Require all denied
</FilesMatch>