docs: add P0 auth spoofing mitigation findings (§10.2.1)

Applied iptables firewall on VM 1130 to restrict ports 8420/8440
to CT 101 (Caddy) and localhost only. Documents Tailscale ts-input
chain ordering requirement for future firewall work.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Matt 2026-04-26 02:02:38 +00:00
commit db078caa93

View file

@ -212,6 +212,96 @@ SSH access to CT 101 from Matt's workstation requires jump through cortex (192.1
- Document the current vhost structure to inform the migration patch
- Append findings to this doc as §10.2 appendix
### 10.2.1 — P0 Mitigation Applied (2026-04-25)
#### Vulnerability Description
**CRITICAL:** RECON backends (ports 8420, 8440) bound to `0.0.0.0` with no firewall rules, accepting the `X-Authentik-Username` header unconditionally. Any host on the LAN (192.168.1.0/24) or Tailscale network (100.64.0.0/10) could bypass Caddy entirely, connect directly to backends, and spoof any user identity via HTTP header injection.
**Verified exploitation:** From cortex (100.64.0.14), we successfully read all contacts, added/removed API keys, and accessed admin functions using a single spoofed header.
Caddy itself was NOT vulnerable—the `forward_auth` directive properly authenticates and `copy_headers` overwrites client-supplied headers. The vulnerability was **unprotected direct backend access**.
#### Mitigation Summary
Applied iptables firewall rules on VM 1130 (RECON host) restricting ports 8420 and 8440 to three allowed sources:
1. **localhost** (lo interface) — for internal health checks and local tooling
2. **CT 101 LAN IP** (192.168.1.101) — Caddy reverse proxy
3. **CT 101 Tailscale IP** (100.64.0.8) — Caddy reverse proxy via Tailscale
All other traffic to these ports is dropped.
#### Tailscale iptables Ordering Requirement
**Critical implementation note:** On hosts running Tailscale, the `ts-input` chain is jumped to early in the INPUT chain and accepts all traffic from the `tailscale0` interface before any subsequent rules are evaluated.
```
Chain INPUT (policy ACCEPT)
num target prot source destination
1 ts-input all 0.0.0.0/0 0.0.0.0/0 ← Tailscale jumps here first
...
```
Inside `ts-input`, rule 4 is typically `ACCEPT all -- tailscale0 * 0.0.0.0/0 0.0.0.0/0`, which accepts ALL Tailscale traffic unconditionally.
**Consequence:** Any port-specific DROP rules appended to INPUT will never be reached for Tailscale traffic. Custom firewall rules on Tailscale hosts **must be inserted at position 1** (before the ts-input jump) to take effect.
```bash
# WRONG — will never block Tailscale traffic:
iptables -A INPUT -p tcp --dport 8420 -j DROP
# CORRECT — inserted before ts-input:
iptables -I INPUT 1 -p tcp --dport 8420 -j DROP
```
#### Final Rule Set
Rules applied and persisted via `netfilter-persistent`:
```
Chain INPUT (policy ACCEPT)
num target prot in source dport comment
1 ACCEPT tcp lo 0.0.0.0/0 8420 P0 auth spoofing fix 2026-04-25
2 ACCEPT tcp * 192.168.1.101 8420 P0 auth spoofing fix 2026-04-25
3 ACCEPT tcp * 100.64.0.8 8420 P0 auth spoofing fix 2026-04-25
4 DROP tcp * 0.0.0.0/0 8420 P0 auth spoofing fix 2026-04-25
5 ACCEPT tcp lo 0.0.0.0/0 8440 P0 auth spoofing fix 2026-04-25
6 ACCEPT tcp * 192.168.1.101 8440 P0 auth spoofing fix 2026-04-25
7 ACCEPT tcp * 100.64.0.8 8440 P0 auth spoofing fix 2026-04-25
8 DROP tcp * 0.0.0.0/0 8440 P0 auth spoofing fix 2026-04-25
9 ts-input all * 0.0.0.0/0 * (Tailscale chain)
```
#### Verification Results
| Test | Expected | Actual |
|------|----------|--------|
| Direct 8420 from cortex (100.64.0.14) | BLOCKED | BLOCKED (8 pkts dropped) |
| Direct 8440 from cortex (100.64.0.14) | BLOCKED | BLOCKED (5 pkts dropped) |
| Direct 8420 from TOC (100.64.0.5) | BLOCKED | BLOCKED |
| Via Caddy (CT 101) → 8440 | ALLOWED | ALLOWED (4 pkts accepted) |
| Localhost → 8420 (health check) | ALLOWED | ALLOWED |
#### Outstanding Items (Broader Auth Migration)
The following remain part of the scheduled migration work and are **not addressed by this P0 fix**:
1. **`header_up -X-Authentik-Username` on Caddy reverse_proxy blocks**
- Defense-in-depth measure to strip client-supplied auth headers before forwarding
- Scheduled for migration session (Phase 3)
- Not urgent: Caddy's `copy_headers` already overwrites these headers with Authentik's response
2. **Other 0.0.0.0-bound services on VM 1130**
- Kiwix (8430), files nginx (8888), Valhalla (8002), Nominatim (8010)
- Lower priority: these services do NOT trust `X-Authentik-Username` header
- Separate audit scheduled; network segmentation may be applied for consistency
3. **Postgres/Samba/NFS/CUPS**
- Separate infrastructure concerns, separate audit
- Not part of the Caddy/RECON auth migration scope
### 10.3 — RECON route inventory
Audit `/opt/recon/lib/api.py` (and any other route definitions) to confirm: