Files
cloud-apache-container/configs/whp-security.conf
T
shadowdaoandClaude Opus 5.5 74648ba34b fix(security): deny config/VCS dotfiles over HTTP on standalone cac and cac-litespeed
Measured on .148: standalone cac served /.env with its contents, and
cac-litespeed served /.env even at mode 0640 (OLS runs as the customer uid
there). shared-httpd and shared-ols already deny these via WHP's drop-ins; the
standalone tiers never got them.

- cac: new configs/whp-security.conf in /etc/httpd/conf.d — the same named
  FilesMatch + DirectoryMatch list as WHP's shared-httpd-security.conf,
  re-rooted to /home.
- cac-litespeed: the same `context exp:` regex as WHP's shared-ols vhconf
  template, added to the vhost template.

Named list (.user.ini .env* .git .svn .hg .bzr .ht* .whp .site-builder), not a
blanket dotfile deny, so /.well-known/ stays reachable. HTTP only: PHP still
reads these files from disk.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 16:31:56 -07:00

30 lines
1.5 KiB
Plaintext

## SECURITY: never serve config / VCS dotfiles over HTTP (standalone cac).
##
## Same named list as WHP's shared-httpd drop-in (web-files/configs/
## shared-httpd-security.conf, 000-whp-security.conf on every shared-httpd host),
## re-rooted from /mnt/users to /home because here the docroot is
## /home/<user>/public_html. Standalone cac never got that drop-in, and measured
## on .148 it served /.env with contents.
##
## <FilesMatch> matches the FILENAME resolved from the filesystem path, not the
## request URL, so it cannot be side-stepped by URL-encoding. httpd applies
## <Directory> sections (and .htaccess) first and <Files>/<FilesMatch> after
## them, so this deny wins over create-vhost.sh's `Require all granted`.
##
## A NAMED LIST, NOT A BLANKET "^\." DENY: /.well-known/ (ACME, security.txt,
## apple-app-site-association, assetlinks.json, payment-domain verification)
## must stay reachable. FilesMatch tests the final path component, and for
## /.well-known/acme-challenge/<token> that is <token>, not a dotfile.
##
## HTTP only: PHP still reads .user.ini and .env off the filesystem as before.
<Directory "/home">
<FilesMatch "^\.(user\.ini|env|git|svn|hg|bzr|ht|whp|site-builder)">
Require all denied
</FilesMatch>
</Directory>
## Directory form: reaches the files INSIDE .git/ etc. (e.g. /.git/config,
## whose own name is not a dotfile).
<DirectoryMatch "^/home/.*/\.(git|svn|hg|bzr|whp|site-builder)(/|$)">
Require all denied
</DirectoryMatch>