# ── PHP version (ISPmanager-style hosting) ───────────────────────────────────
# The app requires PHP 8.0+ (uses str_contains(), match(), mixed, union
# return types). If the panel's PHP version dropdown for this domain doesn't
# offer 8.x directly, forcing the handler here is the fallback. Adjust the
# number to whatever 8.x build is actually installed on this server if 81
# isn't it — check the hosting panel's PHP section for the exact list.
SetHandler application/x-httpd-alt-php81
Options -Indexes
RewriteEngine On
# ── Block direct access to all app internals ─────────────────────────────────
RewriteRule ^app/ - [F,L]
RewriteRule ^storage/ - [F,L]
RewriteRule ^cron/ - [F,L]
# ── Allow static assets (CSS, JS, images — NOT PHP) ──────────────────────────
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} !\.php$
RewriteRule ^ - [L]
# ── Everything else → front controller ───────────────────────────────────────
RewriteRule ^(.*)$ index.php [QSA,L]
# ── Security headers ──────────────────────────────────────────────────────────
Header always set X-Frame-Options "DENY"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# ── Block sensitive file extensions ──────────────────────────────────────────
# Apache 2.4 uses mod_authz_core (Require all denied); Apache 2.2 uses
# mod_access_compat (Order/Deny). Guarding both so this doesn't 500 on
# whichever version the host actually runs.
Require all denied
Order deny,allow
Deny from all
# ── Block direct access to .htaccess itself ──────────────────────────────────
Require all denied
Order deny,allow
Deny from all