fix(@angular/ssr): prevent open redirect via X-Forwarded-Prefix header #32521
Merged
alan-agius4 merged 1 commit intoangular:mainfrom Feb 23, 2026
Merged
Conversation
bdc4f23 to
33629cc
Compare
securityMB
reviewed
Feb 20, 2026
33629cc to
f181214
Compare
Collaborator
Author
|
@dgp1130 & @AndrewKushnir please ignore the first commit as this is from #32516. @josephperrott, I added you by mistake as a reviewer, and I cannot remove you. |
dgp1130
approved these changes
Feb 20, 2026
| @@ -95,26 +95,32 @@ export function addTrailingSlash(url: string): string { | |||
| * ``` | |||
| */ | |||
| export function joinUrlParts(...parts: string[]): string { | |||
Collaborator
There was a problem hiding this comment.
Consider: Could a regex be simpler? Something like:
const regex = new Regex('^/*(?<part>.*?)/*$');
const normalizedParts = parts.map((part) => regex.exec(part).groups['part']);
return addLeadingSlash(normalizedParts.join('/'));
Collaborator
Author
There was a problem hiding this comment.
This is quite a hot function, whilst I didn’t benchmark it I assume the above is much slower.
0755920 to
66cb832
Compare
This change addresses a security vulnerability where `joinUrlParts()` in `packages/angular/ssr/src/utils/url.ts` only stripped one leading slash from URL parts. When the `X-Forwarded-Prefix` header contains multiple leading slashes (e.g., `///evil.com`), the function previously produced a protocol-relative URL (e.g., `//evil.com/home`). If the application issues a redirect (e.g., via a generic redirect route), the browser interprets this 'Location' header as an external redirect to `https://evil.com/home`. This vulnerability poses a significant risk as open redirects can be used in phishing attacks. Additionally, since the redirect response may lack `Cache-Control` headers, intermediate CDNs could cache the poisoned redirect, serving it to other users. This commit fixes the issue by: 1. Updating `joinUrlParts` to internally strip *all* leading and trailing slashes from URL segments, preventing the formation of protocol-relative URLs from malicious input. 2. Adding strict validation for the `X-Forwarded-Prefix` header to immediately reject requests with values starting with multiple slashes (`//`) or backslashes (`\\`). Closes angular#32501
66cb832 to
877f017
Compare
Collaborator
Author
This was referenced Feb 23, 2026
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 addresses a security vulnerability where
joinUrlParts()inpackages/angular/ssr/src/utils/url.tsonly stripped one leading slash from URL parts.When the
X-Forwarded-Prefixheader contains multiple leading slashes (e.g.,///evil.com), the function previously produced a protocol-relative URL (e.g.,//evil.com/home). If the application issues a redirect (e.g., via a generic redirect route), the browser interprets this 'Location' header as an external redirect tohttps://evil.com/home.This vulnerability poses a risk as open redirects can be used in phishing attacks. Additionally, since the redirect response may lack
Cache-Controlheaders, intermediate CDNs could cache the poisoned redirect, serving it to other users.This commit fixes the issue by:
joinUrlPartsto internally strip all leading and trailing slashes from URL segments, preventing the formation of protocol-relative URLs from malicious input.X-Forwarded-Prefixheader to immediately reject requests with values starting with multiple slashes.Closes #32501