From 8717e56a0c8e98a95783739b94910af8cfff449b Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 9 Jun 2026 08:55:11 +0000 Subject: [PATCH] refactor(platform-server): deprecate ServerXhr XHR support in `@angular/platform-server` is deprecated because the underlying `xhr2` library does not safely handle redirects. Specifically, it can forward `Authorization` headers on cross-origin redirects (which leaks credentials) and is susceptible to denial-of-service (DoS) via redirect loops. DEPRECATED: XHR support in `@angular/platform-server` is deprecated. Use standard `fetch` APIs instead. --- packages/platform-server/src/http.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/platform-server/src/http.ts b/packages/platform-server/src/http.ts index 509aba309ce6..f910ce24c0ba 100644 --- a/packages/platform-server/src/http.ts +++ b/packages/platform-server/src/http.ts @@ -20,6 +20,12 @@ import {RuntimeErrorCode} from './errors'; import {resolveUrl} from './url'; @Injectable() +/** + * @deprecated Use the HttpClient fetch backend (by enabling `withFetch()`) instead. + * XHR support in `@angular/platform-server` is deprecated because the underlying `xhr2` + * library does not safely handle redirects (e.g. it can forward `Authorization` headers + * on cross-origin redirects and is susceptible to denial-of-service (DoS) via redirect loops). + */ export class ServerXhr implements XhrFactory { private xhrImpl: typeof import('xhr2') | undefined; @@ -29,6 +35,16 @@ export class ServerXhr implements XhrFactory { // server platform (via shims, etc). private async ɵloadImpl(): Promise { if (!this.xhrImpl) { + if (typeof ngDevMode === 'undefined' || ngDevMode) { + console.warn( + 'XHR support in `@angular/platform-server` is deprecated and will be removed ' + + 'in a future version of Angular. It has known security and performance issues in server ' + + 'environments, such as forwarding `Authorization` headers on cross-origin ' + + 'redirects and susceptibility to denial-of-service (DoS) via redirect loops. ' + + 'Please enable the HttpClient fetch backend instead by using `withFetch()`.', + ); + } + const {default: xhr} = await import('xhr2'); this.xhrImpl = xhr; }