fix(security): drop non-standard X-Host header from trusted proxy headers #1

Merged
eric merged 1 commit from fix/remove-x-host-header into main 2026-06-27 14:41:01 -07:00
Owner

Summary

  • Removes `HTTP_X_HOST` from the trusted-proxy candidate list in `HostHeader::fromServer()` — X-Host is not set by any standard reverse proxy and was undocumented in the trust model
  • Adds `HostHeaderTest` covering the three proxy-header permutations (X-Host ignored with trustProxy=true, X-Forwarded-Host honored with trustProxy=true, X-Forwarded-Host ignored when trust disabled)

Security impact

LOW severity finding from automated audit (2026-06-27). Without caching: self-only response manipulation. With a full-page caching plugin active: potential cache poisoning causing onion URLs to be served to clearnet visitors. Fix is a one-line deletion.

Test plan

  • `composer test` — 34/34 pass (3 new assertions in HostHeaderTest)
  • `composer lint` — clean
  • `composer stan` — clean

🤖 Generated with Claude Code

## Summary - Removes \`HTTP_X_HOST\` from the trusted-proxy candidate list in \`HostHeader::fromServer()\` — X-Host is not set by any standard reverse proxy and was undocumented in the trust model - Adds \`HostHeaderTest\` covering the three proxy-header permutations (X-Host ignored with trustProxy=true, X-Forwarded-Host honored with trustProxy=true, X-Forwarded-Host ignored when trust disabled) ## Security impact LOW severity finding from automated audit (2026-06-27). Without caching: self-only response manipulation. With a full-page caching plugin active: potential cache poisoning causing onion URLs to be served to clearnet visitors. Fix is a one-line deletion. ## Test plan - [x] \`composer test\` — 34/34 pass (3 new assertions in HostHeaderTest) - [x] \`composer lint\` — clean - [x] \`composer stan\` — clean 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(security): drop non-standard X-Host header from trusted proxy headers
All checks were successful
CI / Lint + Static Analysis (pull_request) Successful in 49s
CI / Unit Tests (PHP 8.2) (pull_request) Successful in 46s
CI / Unit Tests (PHP 8.3) (pull_request) Successful in 1m16s
CI / Unit Tests (PHP 8.4) (pull_request) Successful in 1m9s
CI / Unit Tests (PHP 8.5) (pull_request) Successful in 1m13s
b99b82086d
X-Host is not set by any standard reverse proxy (nginx, Apache, HAProxy,
Caddy). Trusting it when TRUST_PROXY=true allowed unauthenticated callers
to inject a configured hostname (e.g. a Tor onion address) via a header
that operators would not think to strip at the proxy layer.

Removes the HTTP_X_HOST candidate from HostHeader::fromServer(). Only
X-Forwarded-Host (RFC 7239 / de facto standard) is trusted in proxy mode.

Adds HostHeaderTest covering: X-Host ignored with trustProxy=true,
X-Forwarded-Host honored with trustProxy=true, X-Forwarded-Host ignored
with trustProxy=false.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
eric merged commit 61b2415dc5 into main 2026-06-27 14:41:01 -07:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
eric/multi-domain-redux!1
No description provided.