Conversation
|
This a duplicate of #69531 As note I don't think this can be considered a security more than harderning. Also to reject a redirect you can use |
a74012c to
f9adbba
Compare
|
Thanks for pointing me to #69531. I reviewed its TransferCache changes and agree that there is overlap around There is one behavior in this PR that #69531 does not appear to cover, though: preserving the final response URL separately from the request URL. #69531 stores The regression here specifically exercises a case where those URLs differ: Current TransferCache replay produces: With the so an interceptor which intentionally follows redirects but validates the final origin would still lose the destination needed for that decision. Angular's interceptor documentation also describes using Regarding The security-relevant framework behavior reported through OSS VRP is the change in the result of the same application policy across the SSR/hydration boundary: The report also contains an end-to-end credential-disclosure consequence under additional application prerequisites. I'm not claiming that Angular applications generally leak credentials; the underlying framework behavior is the provenance change above. I also updated this PR to take the TransferState payload concern raised on #69531 into account. Redirect provenance is now serialized only when meaningful: ...(responseUrl !== null && responseUrl !== requestUrl
? {[RESPONSE_URL]: responseUrl}
: {}),
...(redirected === true ? {[REDIRECTED]: true} : {}),Therefore, for a non-redirected response whose final URL equals the request URL, neither additional field is serialized. There is now a regression test for that behavior as well. |
There was a problem hiding this comment.
Thanks for working on this.
Please note that this change is considered hardening rather than a security issue.
Please update the commit header from fix(common) to fix(http) per the Angular commit guidelines. I also left a few additional comments inline next to the code.
f9adbba to
7f0f410
Compare
|
Thanks for the review. I've pushed an updated version of the PR and addressed the requested changes. Changes made:
The focused Regarding the classification as hardening rather than a security issue: understood. For my own understanding, could you clarify what makes this fall on the hardening side? The reason I ask is that the report demonstrates a case where the same redirect-aware application policy can produce different results across SSR and hydration because the transferred response loses the final response URL / redirect provenance. Under the additional application prerequisites described in the report, we were also able to demonstrate a conditional credential-disclosure chain: an attacker-controlled redirected response could be accepted from TransferCache during hydration, influence a runtime API base URL, and cause a later application auth interceptor to send a bearer token to the attacker-controlled origin. The same chain was blocked when the real redirect provenance was preserved. I'm not suggesting that Angular directly leaks credentials in every application, since the token-disclosure step depends on application-specific behavior and the prerequisites described in the report. I'm mainly trying to understand which part of that demonstrated chain is considered outside Angular's security boundary, so I can apply the same criterion to future reports. |
|
Regarding the classification as hardening versus a security vulnerability: In the context of the framework, a security vulnerability generally refers to a flaw where Angular directly enables an exploit or breaks an internal security boundary (for example, a sanitizer bypass, template injection leading to XSS, or an SSRF triggered by framework internals). In this case:
Thanks again. |
|
Can you please address the testing failure. (the internal test one is a flake). |
Preserve the final response URL and redirected flag when HTTP responses are serialized into TransferState and replayed on the client. This ensures redirect-aware interceptors observe consistent response provenance across SSR and client hydration. Only serialize redirect provenance when it is meaningful: redirected is stored only for actual redirects, and the final response URL is stored only when it differs from the request URL. This avoids adding fields to ordinary non-redirected TransferCache entries.
7f0f410 to
b89ec22
Compare
Thanks for pointing this out. I addressed the public testing failure. The issue was that the two new TransferCache symbols, I updated I verified the final commit locally:
The updated commit has now been pushed. |
Fixes 70947
Google OSS VRP referred the underlying report to the Angular maintainers for public issue and pull-request coordination.
Google OSS VRP report:
559659097Problem
HttpTransferCacheserializes a reducedHttpResponseintoTransferState.Before this change, replay did not preserve Fetch redirect provenance:
HttpResponse.redirectedwas lost.HttpResponse.urlwas reconstructed from the TransferCache request URL instead of the final response URL.This can cause redirect-aware application interceptors to observe different response semantics during SSR and browser hydration.
For example:
The linked issue contains the complete security scenario and demonstrated impact.
Change
This patch:
HttpResponse.redirectedwhen provided by the backend;HttpResponse;HTTP_TRANSFER_CACHE_ORIGIN_MAPmapping to the final response URL when applicable.The additional serialized properties are optional, so existing TransferState entries without them continue to use the current request-URL fallback behavior.
Regression test
The regression test:
HttpResponsewithredirected: trueand a different final origin;Against the unmodified implementation on the tested
mainbase:With this patch:
Test target:
ng-dev format changed upstream/main --checkandgit diff --checkalso pass.Scope
This PR addresses the response-provenance loss that causes the demonstrated SSR/browser security-policy mismatch.
It intentionally does not change interceptor ordering or the point at which TransferCache commits a response. Such a change would have broader behavioral implications and can be considered separately if desired.