From db078caa93de8b3f8dd5152d75cd9e2ccc5711c1 Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 26 Apr 2026 02:02:38 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20add=20P0=20auth=20spoofing=20mitigation?= =?UTF-8?q?=20findings=20(=C2=A710.2.1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- AUTH-PUBLIC-FRONTEND.md | 90 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/AUTH-PUBLIC-FRONTEND.md b/AUTH-PUBLIC-FRONTEND.md index 620634c..281e9fe 100644 --- a/AUTH-PUBLIC-FRONTEND.md +++ b/AUTH-PUBLIC-FRONTEND.md @@ -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: