Commit Graph

1 Commits

Author SHA1 Message Date
James Anderson 1f5fb6b42c fix(security): gate x-forwarded-proto in edge API runtime on trustProxy (F-PROD-7) (#1618)
The dev edge API bridge (`createEdgeApiRequest` in `api-handler.ts`) was
reading `X-Forwarded-Proto` without the `trustProxy` gate that the rest of
the prod server uses. A client that can reach the dev server directly
could send `X-Forwarded-Proto: https` and trick edge handlers that gate
Secure-cookie issuance on `request.url.startsWith("https")` (or any other
`request.url.protocol` check) into believing the request was
TLS-terminated.

Same issue applied to `X-Forwarded-Host` in the same function: the raw
header value was used to build the request URL, opening a host-header
poisoning vector identical to the one `prod-server.resolveHost` already
guards against.

This commit:

* Extracts `resolveRequestProtocol`, `resolveRequestHost`, `trustProxy`,
  and `trustedHosts` into a new shared module
  `packages/vinext/src/server/proxy-trust.ts`. The helpers accept both
  Node `IncomingMessage` and Web `Headers` so the same trust policy
  applies in every server flavor.
* Updates `prod-server.ts` to delegate to the shared module
  (re-exporting `resolveHost`, `trustedHosts`, and `trustProxy` to keep
  the existing public surface and the tests that mutate `trustedHosts`
  working).
* Updates `createEdgeApiRequest` to use the new helpers so dev edge API
  routes honour `X-Forwarded-Proto` / `X-Forwarded-Host` only when
  `VINEXT_TRUST_PROXY=1` / `VINEXT_TRUSTED_HOSTS` is configured.

Tests:

* New `tests/api-handler-trust-proxy.test.ts` covers the default
  (untrusted) behaviour, `VINEXT_TRUST_PROXY=1`, and the
  `VINEXT_TRUSTED_HOSTS` allow-list (including the implicit
  `trustProxy` enablement, case-insensitive matching, and
  comma-separated values).
* Updated the existing "uses the first x-forwarded-proto value" test to
  reflect the new (correct) default of ignoring forged proxy headers.

Reference: Finding F-PROD-7 in SECURITY-AUDIT-2026-05.md.
2026-05-27 16:17:16 +01:00