Skip to content

fix(@angular/ssr): enforce explicit opt-in for proxy headers#32911

Draft
alan-agius4 wants to merge 1 commit intoangular:mainfrom
alan-agius4:x-forward-prefix-validation
Draft

fix(@angular/ssr): enforce explicit opt-in for proxy headers#32911
alan-agius4 wants to merge 1 commit intoangular:mainfrom
alan-agius4:x-forward-prefix-validation

Conversation

@alan-agius4
Copy link
Copy Markdown
Collaborator

This commit introduces a secure-by-default model for trusting proxy headers (X-Forwarded-*) in the @angular/ssr package. Previously, the engine relied on complex lazy header patching and regex filters to guard against spoofed headers. However, implicit decoding behaviors by URL constructors can render naive regex filtering ineffective against certain percent-encoded payloads.

To harden the engine against Server-Side Request Forgery (SSRF) and header-spoofing attacks:

  • Introduced the allowedProxyHeaders configuration option to AngularAppEngineOptions and AngularNodeAppEngineOptions.
  • By default (false), all incoming X-Forwarded-* headers are aggressively scrubbed unless explicitly whitelisted via allowedProxyHeaders.
  • Replaced the lazy cloneRequestAndPatchHeaders utility with a simplified, eager sanitizeRequestHeaders that centralizes the header scrubbing logic.
  • Hardened verifyHostAllowed to definitively reject parsed hosts that successfully carry path, search, hash, or auth components, replacing previously fallible regex filters for stringently checked hosts.

BREAKING CHANGE:

The @angular/ssr package now ignores all X-Forwarded-* proxy headers by default. If your application relies on these headers (e.g., for resolving absolute URLs, trust proxy, or custom proxy-related logic), you must explicitly allow them using the new allowedProxyHeaders option in the application server configuration.

Example:

const engine = new AngularAppEngine({
  // Allow all proxy headers
  allowedProxyHeaders: true,
});

// Or explicitly allow specific headers:
const engine = new AngularAppEngine({
  allowedProxyHeaders: ['x-forwarded-host', 'x-forwarded-prefix'],
});

@angular-robot angular-robot bot added detected: breaking change PR contains a commit with a breaking change area: @angular/ssr labels Apr 1, 2026
@alan-agius4 alan-agius4 force-pushed the x-forward-prefix-validation branch 4 times, most recently from 812e774 to 8a649a5 Compare April 1, 2026 12:33
@alan-agius4 alan-agius4 changed the title refactor(@angular/ssr): enforce explicit opt-in for proxy headers fix(@angular/ssr): enforce explicit opt-in for proxy headers Apr 1, 2026
@alan-agius4 alan-agius4 force-pushed the x-forward-prefix-validation branch 2 times, most recently from 5f9bb14 to 8de34e7 Compare April 1, 2026 12:53
This commit introduces a secure-by-default model for trusting proxy
headers (`X-Forwarded-*`) in the `@angular/ssr` package. Previously, the
engine relied on complex lazy header patching and regex filters to guard
against spoofed headers. However, implicit decoding behaviors by URL
constructors can render naive regex filtering ineffective against certain
percent-encoded payloads.

To harden the engine against Server-Side Request Forgery (SSRF) and
header-spoofing attacks:
- Introduced the `allowedProxyHeaders` configuration option to
  `AngularAppEngineOptions` and `AngularNodeAppEngineOptions`.
- By default (`false`), all incoming `X-Forwarded-*` headers are aggressively
  scrubbed unless explicitly whitelisted via `allowedProxyHeaders`.
- Replaced the lazy `cloneRequestAndPatchHeaders` utility with a simplified,
  eager `sanitizeRequestHeaders` that centralizes the header scrubbing logic.
- Hardened `verifyHostAllowed` to definitively reject parsed hosts that successfully
  carry path, search, hash, or auth components, replacing previously fallible
  regex filters for stringently checked hosts.

BREAKING CHANGE:

The `@angular/ssr` package now ignores all `X-Forwarded-*` proxy headers by default. If your application relies on these headers (e.g., for resolving absolute URLs, trust proxy, or custom proxy-related logic), you must explicitly allow them using the new `allowedProxyHeaders` option in the application server configuration.

Example:
```ts
const engine = new AngularAppEngine({
  // Allow all proxy headers
  allowedProxyHeaders: true,
});

// Or explicitly allow specific headers:
const engine = new AngularAppEngine({
  allowedProxyHeaders: ['x-forwarded-host', 'x-forwarded-prefix'],
});
```
@alan-agius4 alan-agius4 force-pushed the x-forward-prefix-validation branch from 8de34e7 to 2cf1919 Compare April 1, 2026 12:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: @angular/ssr detected: breaking change PR contains a commit with a breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant