# Production security rules for Apache 2.4 / standard cPanel hosting.
# These rules restrict HTTP requests only; server-side PHP may still read .env.

# Never expose a directory index when no index file exists.
Options -Indexes

# Deny every environment file, including variants such as .env.production
# and .env.local. Keep this rule explicit and near the top of the file.
<FilesMatch "^\.env">
    Require all denied
</FilesMatch>

# Deny sensitive configuration, log, database, dump, and backup formats.
# A compressed SQL dump such as database.sql.gz is covered as well.
<FilesMatch "(?i)(?:\.(?:env|ini|log|conf|config|ya?ml|sql|sqlite3?|db|dump|bak|backup|old|orig|save|dist|md|markdown|rst|adoc)(?:\.(?:gz|bz2|xz|zip|7z))?|~)$">
    Require all denied
</FilesMatch>

# Deny compressed archives whose names indicate a backup, export, snapshot,
# database copy, or dump without blocking intentional public download archives.
<FilesMatch "(?i)^.*(?:backup|dump|database|db|export|snapshot|copy).*\.(?:zip|7z|tar|tgz|gz|bz2|xz)$">
    Require all denied
</FilesMatch>

# Deny dependency metadata, application configuration, development tooling,
# and internal documentation that do not need to be served by the website.
<FilesMatch "(?i)^(?:composer\.(?:json|lock)|auth\.json|config(?:uration)?(?:\..+)?|database(?:\..+)?|db(?:\..+)?|settings(?:\..+)?|secrets?(?:\..+)?|credentials?(?:\..+)?|phpunit(?:\..+)?|phpstan(?:\..+)?|psalm(?:\..+)?|readme(?:\..+)?|changelog(?:\..+)?|contributing(?:\..+)?|security(?:\..+)?|license(?:\..+)?)$">
    Require all denied
</FilesMatch>

<IfModule mod_rewrite.c>
    RewriteEngine On

    # Block dotfiles and dot-directories (including .git and its contents).
    # Root-level .well-known remains available for ACME/SSL validation.
    RewriteRule "(^|/)\.(?!well-known(?:/|$))" "-" [F,L,NC]

    # Defense in depth for Git metadata and common repository endpoints.
    RewriteRule "(^|/)\.git(?:/|$)" "-" [F,L,NC]

    # Application/private directories remain readable by PHP on the server,
    # but cannot be requested directly over HTTP.
    RewriteRule "(^|/)(?:config|database|includes|logs?|backups?|docs?|storage|vendor)(?:/|$)" "-" [F,L,NC]

    # Send clean, non-file URLs to the PHP front controller.
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^ index.php [QSA,L]
</IfModule>

DirectoryIndex index.php

<IfModule mod_headers.c>
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
</IfModule>

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/css text/javascript application/javascript application/json application/xml image/svg+xml
</IfModule>

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/css "access plus 7 days"
    ExpiresByType application/javascript "access plus 7 days"
    ExpiresByType image/avif "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
</IfModule>

# php -- BEGIN cPanel-generated handler, do not edit
# Set the “ea-php74” package as the default “PHP” programming language.
<IfModule mime_module>
  AddHandler application/x-httpd-ea-php74___lsphp .php .php7 .phtml
</IfModule>
# php -- END cPanel-generated handler, do not edit
