# Enable mod_rewrite RewriteEngine On # Security headers # The first rule is to prevent including in a frame on a different domain. # Remove it if you want to do that. Header always set X-Frame-Options "SAMEORIGIN" Header always set X-XSS-Protection "1; mode=block" Header always set X-Content-Type-Options "nosniff" # Directory index # (Not actually used because everything gets handled by a rewrite rule # , but I'm keeping it for clarity about what's going on.) DirectoryIndex index.php # Deny access to hidden files (e.g. .htaccess) Require all denied # Cache static files (excluding css/custom which goes through PHP) # Note that I don't actually serve most of this (just css) # but this prevents requests for static content from getting to the PHP handler. # # The /css/custom directory is excluded from this in a RewriteCond below: # RewriteCond %{REQUEST_URI} !^/tkr/css/custom/ # # Those requests are handled by the PHP app to serve custom css ExpiresActive On ExpiresDefault "access plus 1 year" Header set Cache-Control "public, max-age=31536000, immutable" # Process PHP files SetHandler application/x-httpd-php # Skip rewriting if already in /tkr/public/ (prevents infinite loops) RewriteRule ^tkr/public/ - [L] # Block direct access to all .php files # but allow internal rewrites to index.php RewriteCond %{THE_REQUEST} \.php [NC] RewriteRule ^.*\.php$ - [R=404,L] # Block access to sensitive directories RewriteRule ^(storage|src|templates|uploads|config)(/.*)?$ - [F,L] # If it's a static file that exists in /tkr/public, serve it directly # (but exclude css/custom which should go through PHP) RewriteCond %{REQUEST_URI} !^/css/custom/ RewriteCond %{DOCUMENT_ROOT}/tkr/public%{REQUEST_URI} -f RewriteRule ^(.*)$ /tkr/public/$1 [L] # Send everything else to the front controller # (/tkr/public/index.php) RewriteRule ^.*$ /tkr/public/index.php [L]