Skip to content

fix(@angular/ssr): validate host headers to prevent header-based SSRF [LTS 20]#32498

Open
alan-agius4 wants to merge 1 commit intoangular:20.3.xfrom
alan-agius4:security-ssr-20
Open

fix(@angular/ssr): validate host headers to prevent header-based SSRF [LTS 20]#32498
alan-agius4 wants to merge 1 commit intoangular:20.3.xfrom
alan-agius4:security-ssr-20

Conversation

@alan-agius4
Copy link
Collaborator

@alan-agius4 alan-agius4 commented Feb 17, 2026

This change introduces strict validation for Host, X-Forwarded-Host, X-Forwarded-Proto, and X-Forwarded-Port headers in the Angular SSR request handling pipeline, including CommonEngine and AngularAppEngine.

Previously, the application engine constructed the base URL for server-side rendering using these headers without validation. This could allow an attacker to manipulate the headers to steer relative HttpClient requests to arbitrary internal or external hosts (SSRF).

With this change:

  • The Host and X-Forwarded-Host headers are validated against a strict allowlist.
  • localhost and loopback addresses (e.g., 127.0.0.1, [::1]) are allowed by default.
  • X-Forwarded-Port must be numeric.
  • X-Forwarded-Proto must be http or https.
  • Requests with invalid or disallowed headers will now be rejected with a 400 Bad Request status code.

BREAKING CHANGE:

Server-side requests will now fail with a 400 Bad Request error if the Host header does not match a customized allowlist (or localhost).

AngularAppEngine Users:
To resolve this, you must configure the allowedHosts option in your angular.json to include all domain names where your application is deployed.

Example configuration in angular.json:

"architect": {
  "build": {
    "options": {
      "security": {
        "allowedHosts": ["example.com", "*.trusted-example.com"]
      }
    }
  }
}

CommonEngine Users:
If you are using CommonEngine, you must now provide the allowedHosts option when initializing or rendering your application.

Example:

const commonEngine = new CommonEngine({
  allowedHosts: [“example.com”, *.trusted-example.com"]
});

@angular-robot angular-robot bot added detected: breaking change PR contains a commit with a breaking change area: @angular/ssr labels Feb 17, 2026
@alan-agius4 alan-agius4 force-pushed the security-ssr-20 branch 4 times, most recently from 1ef9e0d to 94c33aa Compare February 17, 2026 09:09
@alan-agius4 alan-agius4 added the target: lts This PR is targeting a version currently in long-term support label Feb 17, 2026
@alan-agius4 alan-agius4 force-pushed the security-ssr-20 branch 3 times, most recently from 0a392ef to 9415df8 Compare February 17, 2026 09:46
@alan-agius4 alan-agius4 added the action: review The PR is still awaiting reviews from at least one requested reviewer label Feb 17, 2026
@alan-agius4 alan-agius4 marked this pull request as ready for review February 17, 2026 10:40
@alan-agius4 alan-agius4 changed the title fix(@angular/ssr): validate host headers to prevent header-based SSRF fix(@angular/ssr): validate host headers to prevent header-based SSRF [LTS 20] Feb 17, 2026
@alan-agius4 alan-agius4 force-pushed the security-ssr-20 branch 2 times, most recently from 49db643 to 9dedaae Compare February 18, 2026 10:25
This change introduces strict validation for `Host`, `X-Forwarded-Host`, `X-Forwarded-Proto`, and `X-Forwarded-Port` headers in the Angular SSR request handling pipeline, including `CommonEngine` and `AngularAppEngine`.

Previously, the application engine constructed the base URL for server-side rendering using these headers without validation. This could allow an attacker to manipulate the headers to steer relative `HttpClient` requests to arbitrary internal or external hosts (SSRF).

With this change:
- The `Host` and `X-Forwarded-Host` headers are validated against a strict allowlist.
- `localhost` and loopback addresses (e.g., `127.0.0.1`, `[::1]`) are allowed by default.
- `X-Forwarded-Port` must be numeric.
- `X-Forwarded-Proto` must be `http` or `https`.
- Requests with invalid or disallowed headers will now be rejected with a `400 Bad Request` status code.

BREAKING CHANGE:

Server-side requests will now fail with a `400 Bad Request` error if the `Host` header does not match a customized allowlist (or localhost).

**AngularAppEngine Users:**
To resolve this, you must configure the `allowedHosts` option in your `angular.json` to include all domain names where your application is deployed.

Example configuration in `angular.json`:

```json
"architect": {
  "build": {
    "options": {
      "security": {
        "allowedHosts": ["example.com", "*.trusted-example.com"]
      }
    }
  }
}
```

**CommonEngine Users:**
If you are using `CommonEngine`,  you must now provide the `allowedHosts` option when initializing or rendering your application.

Example:
```typescript
const commonEngine = new CommonEngine({
  allowedHosts: [“example.com”, “*.trusted-example.com"]
});
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: review The PR is still awaiting reviews from at least one requested reviewer area: @angular/ssr detected: breaking change PR contains a commit with a breaking change target: lts This PR is targeting a version currently in long-term support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants