|
1 | 1 | # ------------------------------------------ |
2 | | -# 🔒 Disable PHP execution for security |
| 2 | +# 🔒 Static content hardening |
3 | 3 | # ------------------------------------------ |
4 | | -<FilesMatch "\.(php|php[0-9]*)$"> |
5 | | - Order allow,deny |
6 | | - Deny from all |
| 4 | + |
| 5 | +Options -Indexes |
| 6 | + |
| 7 | +# Disable PHP-like execution/access in static content directory. |
| 8 | +<FilesMatch "\.(?:php|phtml|phar|php[0-9]*)$"> |
| 9 | + <IfModule mod_authz_core.c> |
| 10 | + Require all denied |
| 11 | + </IfModule> |
| 12 | + <IfModule !mod_authz_core.c> |
| 13 | + Order allow,deny |
| 14 | + Deny from all |
| 15 | + </IfModule> |
7 | 16 | </FilesMatch> |
8 | 17 |
|
9 | | -# Alternative: Serve PHP files as plain text (uncomment if preferred) |
10 | | -# <FilesMatch "\.(php|php[0-9]*)$"> |
11 | | -# SetHandler none |
12 | | -# ForceType text/plain |
13 | | -# </FilesMatch> |
| 18 | +# Prevent this static host from setting cookies. |
| 19 | +# Note: this does not stop parent-domain cookies from being sent here. |
| 20 | +<IfModule mod_headers.c> |
| 21 | + Header always unset Set-Cookie |
| 22 | +</IfModule> |
14 | 23 |
|
15 | 24 | # ------------------------------------------ |
16 | | -# 🚀 Enable browser caching for static files |
| 25 | +# 🚀 Browser caching |
17 | 26 | # ------------------------------------------ |
18 | 27 | <IfModule mod_expires.c> |
19 | 28 | ExpiresActive On |
20 | 29 |
|
21 | | - # Set long expiration for common static file types |
22 | 30 | ExpiresByType image/jpg "access plus 1 year" |
23 | 31 | ExpiresByType image/jpeg "access plus 1 year" |
24 | 32 | ExpiresByType image/gif "access plus 1 year" |
25 | 33 | ExpiresByType image/png "access plus 1 year" |
| 34 | + ExpiresByType image/webp "access plus 1 year" |
| 35 | + ExpiresByType image/avif "access plus 1 year" |
26 | 36 | ExpiresByType image/svg+xml "access plus 1 year" |
| 37 | + |
27 | 38 | ExpiresByType text/css "access plus 1 month" |
28 | 39 | ExpiresByType text/javascript "access plus 1 month" |
29 | 40 | ExpiresByType application/javascript "access plus 1 month" |
30 | 41 | ExpiresByType application/x-javascript "access plus 1 month" |
| 42 | + |
31 | 43 | ExpiresByType application/font-woff2 "access plus 1 year" |
32 | 44 | ExpiresByType application/font-woff "access plus 1 year" |
33 | 45 | ExpiresByType application/vnd.ms-fontobject "access plus 1 year" |
| 46 | + ExpiresByType font/woff2 "access plus 1 year" |
| 47 | + ExpiresByType font/woff "access plus 1 year" |
34 | 48 | ExpiresByType font/ttf "access plus 1 year" |
35 | 49 | ExpiresByType font/otf "access plus 1 year" |
36 | 50 | </IfModule> |
37 | 51 |
|
38 | 52 | # ------------------------------------------ |
39 | | -# 💨 Enable GZIP compression |
| 53 | +# 💨 Compression |
40 | 54 | # ------------------------------------------ |
41 | 55 | <IfModule mod_deflate.c> |
42 | 56 | AddOutputFilterByType DEFLATE text/plain |
43 | 57 | AddOutputFilterByType DEFLATE text/html |
44 | 58 | AddOutputFilterByType DEFLATE text/xml |
45 | 59 | AddOutputFilterByType DEFLATE text/css |
| 60 | + AddOutputFilterByType DEFLATE text/javascript |
46 | 61 | AddOutputFilterByType DEFLATE application/javascript |
47 | | - AddOutputFilterByType DEFLATE application/x-javascript |
48 | 62 | AddOutputFilterByType DEFLATE application/json |
49 | 63 | AddOutputFilterByType DEFLATE application/xml |
50 | | - AddOutputFilterByType DEFLATE application/font-woff2 |
51 | | - AddOutputFilterByType DEFLATE application/font-woff |
52 | | - AddOutputFilterByType DEFLATE font/ttf |
53 | | - AddOutputFilterByType DEFLATE font/otf |
| 64 | + AddOutputFilterByType DEFLATE image/svg+xml |
54 | 65 |
|
55 | | - # Optional: compress everything except images |
56 | | - SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary |
| 66 | + # Do not gzip already-compressed binary assets. |
| 67 | + SetEnvIfNoCase Request_URI "\.(?:gif|jpe?g|png|webp|avif|ico|woff2?|ttf|otf|eot)$" no-gzip dont-vary |
57 | 68 | </IfModule> |
58 | 69 |
|
59 | 70 | # ------------------------------------------ |
60 | | -# 🎯 Leverage cache-control headers |
| 71 | +# 🎯 Cache-Control and security headers |
61 | 72 | # ------------------------------------------ |
62 | 73 | <IfModule mod_headers.c> |
63 | | - <FilesMatch "\.(ico|jpg|jpeg|png|gif|svg|css|js|woff|woff2|ttf|otf|eot)$"> |
| 74 | + <FilesMatch "\.(?:ico|jpg|jpeg|png|gif|webp|avif|svg|css|js|map|woff|woff2|ttf|otf|eot)$"> |
64 | 75 | Header set Cache-Control "public, max-age=31536000, immutable" |
65 | 76 | </FilesMatch> |
66 | | -</IfModule> |
67 | 77 |
|
68 | | -# ------------------------------------------ |
69 | | -# 🛡️ Basic security headers |
70 | | -# ------------------------------------------ |
71 | | -<IfModule mod_headers.c> |
72 | 78 | Header set X-Content-Type-Options "nosniff" |
73 | | - Header set X-Frame-Options "SAMEORIGIN" |
74 | | - Header set X-XSS-Protection "1; mode=block" |
75 | 79 | Header always set Referrer-Policy "strict-origin-when-cross-origin" |
76 | 80 | </IfModule> |
77 | | - |
78 | | -# ------------------------------------------ |
79 | | -# 🔍 Optional: Redirect to HTTPS if not already handled globally |
80 | | -# ------------------------------------------ |
81 | | -# RewriteEngine On |
82 | | -# RewriteCond %{HTTPS} off |
83 | | -# RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] |
84 | | - |
85 | | -# ------------------------------------------ |
86 | | -# 🧼 Optional: Remove trailing slashes |
87 | | -# ------------------------------------------ |
88 | | -# RewriteCond %{REQUEST_FILENAME} !-d |
89 | | -# RewriteRule ^(.+)/$ /$1 [R=301,L] |
0 commit comments