# ------------------------------------------------------------------
# .htaccess
#
# The backup contained no .htaccess at all, which meant that every file
# under /sec/ was reachable over HTTP, including the one holding the AWS
# keys and the database password. A single missing directive is the
# difference between a config file and a public one.
#
# This requires "AllowOverride All" (or at least FileInfo Limit Options
# AuthConfig) for the directory in the Apache vhost. If the server is set
# to AllowOverride None these rules are silently ignored, so confirm with
# tools/verify_install.php after deploying.
# ------------------------------------------------------------------

# ---------- never serve these ----------

<FilesMatch "\.(ini|log|sql|sh|bak|backup|old|orig|save|swp|dist|lock|md|json|yml|yaml)$">
    Require all denied
</FilesMatch>

# Anything that looks like a dated or annotated backup copy. The backup
# held files such as acmtest_backup_22JUL2024.php sitting live on the
# server, each one a second, unmaintained copy of a page.
<FilesMatch "(_backup|_bak|_old|_copy|~)">
    Require all denied
</FilesMatch>

# Dotfiles.
<FilesMatch "^\.">
    Require all denied
</FilesMatch>

# The debug script found at the root of the backup, which called
# print_r() on a directory listing.
<FilesMatch "^(dir|test|phpinfo|info)\.php$">
    Require all denied
</FilesMatch>

# ---------- directories that must never be browsed ----------

RedirectMatch 404 ^/sec/config/
RedirectMatch 404 ^/sec/lib/
RedirectMatch 404 ^/sec/tools/
RedirectMatch 404 ^/sec/partials/
RedirectMatch 404 ^/sec/vendor/
RedirectMatch 404 ^/sec/smtp/
RedirectMatch 404 ^/sec/docs/

# ---------- no directory listings ----------

Options -Indexes -ExecCGI
Options -FollowSymLinks +SymLinksIfOwnerMatch

# ---------- headers ----------
# Also set from PHP in lib/bootstrap.php. Repeated here so that static
# files, which never reach PHP, carry them too.

<IfModule mod_headers.c>
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set Referrer-Policy "same-origin"
    Header always unset X-Powered-By
    Header always unset Server
</IfModule>

# ---------- force HTTPS ----------

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteCond %{HTTPS} off
    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

# ---------- PHP hardening ----------

<IfModule mod_php7.c>
    php_flag  display_errors        Off
    php_flag  log_errors            On
    php_flag  expose_php            Off
    php_flag  allow_url_fopen       Off
    php_flag  allow_url_include     Off
    php_value session.cookie_httponly 1
    php_value session.use_strict_mode 1
</IfModule>

# ---------- default document ----------

DirectoryIndex index.php
