Skip to content

fix(platform-server): resolve HTTP(S) URLs without authority as relative during SSR - #70450

Open
alan-agius4 wants to merge 1 commit into
angular:mainfrom
alan-agius4:fix-ssr-relative-url
Open

fix(platform-server): resolve HTTP(S) URLs without authority as relative during SSR#70450
alan-agius4 wants to merge 1 commit into
angular:mainfrom
alan-agius4:fix-ssr-relative-url

Conversation

@alan-agius4

Copy link
Copy Markdown
Contributor

Under the WHATWG URL standard, HTTP and HTTPS URLs lacking an authority (e.g., http:/path or http:path) resolve as relative paths when resolved against an origin of the same scheme. Previously, relativeUrlsTransformerInterceptorFn treated any URL with a scheme as an absolute URL, bypassing base resolution in SSR and allowing Node fetch to parse the path as a cross-origin host.

This commit updates SSR URL resolution and the HTTP interceptor to ensure HTTP(S) URLs without an authority are resolved against the current origin, preventing unexpected origin changes and aligning SSR with browser behavior.

Fixes #70447

…ive during SSR

Under the WHATWG URL standard, HTTP and HTTPS URLs lacking an authority
(e.g., `http:/path` or `http:path`) resolve as relative paths when resolved
against an origin of the same scheme. Previously, `relativeUrlsTransformerInterceptorFn`
treated any URL with a scheme as an absolute URL, bypassing base resolution in SSR
and allowing Node fetch to parse the path as a cross-origin host.

This commit updates SSR URL resolution and the HTTP interceptor to ensure
HTTP(S) URLs without an authority are resolved against the current origin,
preventing unexpected origin changes and aligning SSR with browser behavior.

Fixes angular#70447
@pullapprove
pullapprove Bot requested a review from kirjs August 28, 2026 08:37
@angular-robot angular-robot Bot added the area: server Issues related to server-side rendering label Aug 28, 2026
@ngbot ngbot Bot added this to the Backlog milestone Aug 28, 2026
@alan-agius4
alan-agius4 requested review from JeanMeche and removed request for kirjs August 28, 2026 08:37
@alan-agius4 alan-agius4 added action: review The PR is still awaiting reviews from at least one requested reviewer target: patch This PR is targeted for the next patch release labels Aug 28, 2026
@alan-agius4 alan-agius4 added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Aug 28, 2026
@VenkatKwest

Copy link
Copy Markdown

Two corrections from re-testing against real builds.

1. I mis-attributed the regression point. This isn't a bypass of the GHSA-f6mr-pjwc-34m4 fix — your "no framework mutation" point is correct. The only change that fix made under packages/platform-server/src/ was removing urlStr = urlStr.trim(), and trim() is a no-op on these payloads, so behaviour is identical on v22.1.3 and v22.1.4.

It regressed earlier, in 140c4d04cb (fix(platform-server): prevent SSRF bypasses via backslash URLs in HttpClient, 2026-05-27). Before that commit the interceptor was:

const newUrl = new URL(request.url, baseUrl).toString();

which resolved http:/attacker.example/steal against the base as a same-origin path. The URL_SCHEMA_REGEXP early-return added there is what changed it. The same pre-change code is on 20.3.x and 21.2.x. Shipped in v19.2.25, v20.3.24, v21.2.15, v22.0.0, v22.1.0.

2. Affected configurations. Rebuilt the reproduction from the issue against each release line:

platform-server backend outbound cross-origin request issued?
20.3.30 default (HttpXhrBackend) no — request fails
20.3.30 withFetch() yes, with the Authorization header
21.2.22 default (HttpXhrBackend) no — request fails
21.2.22 withFetch() yes, with the Authorization header
22.1.4 default (FetchBackend) yes, with the Authorization header

HttpXhrBackend is unaffected because xhr2's _parseUrl uses Node's legacy url.parse(..., false, true), which returns host: null for http:/host/path. So 20.3.x and 21.2.x are affected when withFetch() is enabled, and 22.x by default.

The PR targets main — flagging in case a cherry-pick to 21.2.x / 20.3.x is wanted.

To be clear, the reported behaviour is unchanged: an unauthenticated request causes the server to issue a cross-origin request to an attacker-chosen host with the application's Authorization header attached, after the application's WHATWG same-origin check passed. Only the attribution was wrong, not the finding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: merge The PR is ready for merge by the caretaker area: server Issues related to server-side rendering target: patch This PR is targeted for the next patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SSRF in @angular/platform-server: http:/host/path URLs bypass the GHSA-f6mr-pjwc-34m4 fix

3 participants