# ⚠️ MANDATORY: Apache vhost patch

**Verification (2026-05-19) found that Apache is ignoring `.htaccess` files
under `chat/`, `private/`, and `logs/`.** All the file-blocking rules added
this session are currently no-ops. Three high-severity exposures are still
live on the public internet:

| URL | Current status | Should be |
|---|---|---|
| `https://crivello.dyndns.org/WebRTC/chat/chat.db` (54 MB) | **200 OK** | 403 |
| `https://crivello.dyndns.org/WebRTC/private/AuthKey_M8988XSBNP.p8` (APNs key) | **200 OK** | 403 |
| `https://crivello.dyndns.org/WebRTC/private/chat.db.pre-encryption.bak` (35 MB plaintext DB) | **200 OK** | 403 |
| `https://crivello.dyndns.org/WebRTC/logs/` (full debug-log archive) | **200 OK** | 403 |

`public/.htaccess` is honored, so the vhost has `AllowOverride` enabled only
for `public/`. The fix is to set `AllowOverride All` for the WebRTC root.

## Patch

SSH to the Pi and edit the vhost (likely `/etc/apache2/sites-available/000-default.conf`
or `/etc/apache2/sites-available/default-ssl.conf`):

```bash
ssh pi
sudo find /etc/apache2/sites-available -name '*.conf' -exec grep -l 'WebRTC\|/var/www/html' {} \;
sudo nano <vhost-file>
```

Inside the `<VirtualHost ...>` block, ADD or REPLACE any existing
`<Directory>` stanzas for `/var/www/html` with these two:

```apache
    # Allow .htaccess to take effect across the whole WebRTC tree.
    <Directory /var/www/html/WebRTC>
        AllowOverride All
        Options -Indexes -MultiViews FollowSymLinks
        Require all granted
    </Directory>

    # Belt-and-braces: deny secrets even if a child .htaccess is ever removed.
    <DirectoryMatch "^/var/www/html/WebRTC/(private|logs)/">
        Require all denied
    </DirectoryMatch>

    # Block direct download of .db / .bak / .p8 / .env / .log anywhere.
    <FilesMatch "\.(db|db-journal|db-wal|db-shm|bak|old|p8|env|log|sql)$">
        Require all denied
    </FilesMatch>
```

`-MultiViews` is important — without it, Apache's content negotiation can
serve `/chat/chat.db.old` as `/chat/chat.db` and similar surprises (that's
why the verification showed `300 Multiple Choices`).

Then reload Apache:

```bash
sudo apache2ctl configtest && sudo systemctl reload apache2
```

## Re-verify

After the reload, run from your Mac:

```bash
for url in \
  'https://crivello.dyndns.org/WebRTC/chat/chat.db' \
  'https://crivello.dyndns.org/WebRTC/private/AuthKey_M8988XSBNP.p8' \
  'https://crivello.dyndns.org/WebRTC/private/chat.db.pre-encryption.bak' \
  'https://crivello.dyndns.org/WebRTC/logs/' \
  'https://crivello.dyndns.org/WebRTC/chat/upload_debug.log'
do
  printf '%-80s -> %s\n' "$url" "$(curl -sk -o /dev/null -w '%{http_code}' "$url")"
done
```

Every line should show **403** (or 404 if the file doesn't exist). If you
still see 200, the vhost change did not take effect — verify `apache2ctl -S`
shows the right config and that `mod_authz_core` is loaded
(`Require` directives need it).

## If you can't edit the vhost right now

Treat as an emergency: at minimum, manually rename or delete the three
flagrant exposures from your Mac:

```bash
# Remove the plaintext-message DB backup entirely.
rm /Users/laurent/Raspberry/WebRTC/private/chat.db.pre-encryption.bak

# Rename the APNs key to something attacker can't guess. Update
# chat/send_push.php's $P8_FILE default to match if you do this.
NEWNAME="apns-$(openssl rand -hex 12).p8"
mv /Users/laurent/Raspberry/WebRTC/private/AuthKey_M8988XSBNP.p8 \
   /Users/laurent/Raspberry/WebRTC/private/$NEWNAME
```

Then **revoke the APNs key in Apple Developer Console** regardless — assume
it has already been leaked.
