# =====================================================================
# Bedrock Shield — Apache/.htaccess hardening snippet
# Paste ABOVE the "# BEGIN WordPress" block in the site root .htaccess.
# PHP-level rules cannot protect truly static files; these do.
# =====================================================================

# --- Block access to sensitive files -------------------------------
<FilesMatch "(?i)(^\.env|^wp-config\.php|^wp-config-sample\.php|\.(sql|sql\.gz|sqlite|bak|old|orig|save|swp|tmp|log|wpress|zip|tar|gz|tgz|7z|rar)$|^readme\.html$|^license\.txt$|^error_log$)">
  Require all denied
</FilesMatch>

# --- Protect wp-config.php explicitly ------------------------------
<Files wp-config.php>
  Require all denied
</Files>

# --- Block hidden dot-directories (.git, .svn, .ht*) ---------------
RedirectMatch 404 (?i)/\.(git|svn|hg|bzr|env)(/|$)

# --- Disable directory listing -------------------------------------
Options -Indexes

# --- Block PHP execution inside uploads ----------------------------
# (A dropped webshell in /uploads/ becomes inert.)
<Directory "wp-content/uploads">
  <FilesMatch "\.(?i:php|php5|php7|phtml|phar|pht|inc)$">
    Require all denied
  </FilesMatch>
</Directory>

# --- Protect the mu-plugins directory listing ----------------------
RedirectMatch 404 (?i)/wp-content/mu-plugins/$

# --- Block xmlrpc.php at the edge (optional; remove if you use it) --
<Files xmlrpc.php>
  Require all denied
</Files>

# --- Limit direct access to wp-login.php by IP (optional) ----------
# <Files wp-login.php>
#   Require ip 203.0.113.0/24
# </Files>

# --- Security headers (if not already set by the app) --------------
<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 "geolocation=(), microphone=(), camera=()"
</IfModule>
