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
Open
fix(@angular/ssr): validate host headers to prevent header-based SSRF [LTS 20]#32498alan-agius4 wants to merge 1 commit intoangular:20.3.xfrom
alan-agius4 wants to merge 1 commit intoangular:20.3.xfrom
Conversation
1ef9e0d to
94c33aa
Compare
0a392ef to
9415df8
Compare
9415df8 to
c1c7510
Compare
dgp1130
approved these changes
Feb 17, 2026
49db643 to
9dedaae
Compare
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"]
});
```
9dedaae to
ff96179
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change introduces strict validation for
Host,X-Forwarded-Host,X-Forwarded-Proto, andX-Forwarded-Portheaders in the Angular SSR request handling pipeline, includingCommonEngineandAngularAppEngine.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
HttpClientrequests to arbitrary internal or external hosts (SSRF).With this change:
HostandX-Forwarded-Hostheaders are validated against a strict allowlist.localhostand loopback addresses (e.g.,127.0.0.1,[::1]) are allowed by default.X-Forwarded-Portmust be numeric.X-Forwarded-Protomust behttporhttps.400 Bad Requeststatus code.BREAKING CHANGE:
Server-side requests will now fail with a
400 Bad Requesterror if theHostheader does not match a customized allowlist (or localhost).AngularAppEngine Users:
To resolve this, you must configure the
allowedHostsoption in yourangular.jsonto include all domain names where your application is deployed.Example configuration in
angular.json:CommonEngine Users:
If you are using
CommonEngine, you must now provide theallowedHostsoption when initializing or rendering your application.Example: