fix(deps): update dependency @angular/platform-server to v20 [security] - #813
Open
renovate[bot] wants to merge 1 commit into
Open
fix(deps): update dependency @angular/platform-server to v20 [security]#813renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
Contributor
Author
|
renovate
Bot
force-pushed
the
renovate/npm-angular-platform-server-vulnerability
branch
from
August 3, 2026 17:11
6c74244 to
8eb0703
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 PR contains the following updates:
~18.2.0→~20.0.0Warning
Some dependencies could not be looked up. Check the Dependency Dashboard for more information.
Angular SSR: Global Platform Injector Race Condition Leads to Cross-Request Data Leakage
CVE-2025-59052 / GHSA-68x2-mx4q-78m7
More information
Details
Impact
Angular uses a DI container (the "platform injector") to hold request-specific state during server-side rendering. For historical reasons, the container was stored as a JavaScript module-scoped global variable. When multiple requests are processed concurrently, they could inadvertently share or overwrite the global injector state.
In practical terms, this can lead to one request responding with data meant for a completely different request, leaking data or tokens included on the rendered page or in response headers. As long as an attacker had network access to send any traffic that received a rendered response, they may have been able to send a large number of requests and then inspect the responses for information leaks.
The following APIs were vulnerable and required SSR-only breaking changes:
bootstrapApplication: This function previously implicitly retrieved the last platform injector that was created. It now requires an explicitBootstrapContextin a server environment. This function is only used for standalone applications. NgModule-based applications are not affected.getPlatform: This function previously returned the last platform instance that was created. It now always returnsnullin a server environment.destroyPlatform: This function previously destroyed the last platform instance that was created. It's now a no-op when called in a server environment.For
bootstrapApplication, the framework now provides a new argument to the application's bootstrap function:As is usually the case for changes to Angular, an automatic schematic will take care of these code changes as part of ng update:
The schematic can also be invoked explicitly if the version bump was pulled in independently:
For applications that still use
CommonEngine, thebootstrapproperty inCommonEngineOptionsalso gains the samecontextargument in the patched versions of Angular.In local development (
ng serve), Angular CLI triggered a codepath for Angular's "JIT" feature on the server even in applications that weren't using it in the browser. The codepath introduced async behavior between platform creation and application bootstrap, triggering the race condition even if an application didn't explicitly usegetPlatformor custom async logic inbootstrap. Angular applications should never run in this mode outside of local development.Patches
The issue has been patched in all active release lines as well as in the v21 prerelease:
@angular/platform-server: 21.0.0-next.3@angular/platform-server: 20.3.0@angular/platform-server: 19.2.15@angular/platform-server:18.2.14@angular/ssr: 21.0.0-next.3@angular/ssr: 20.3.0@angular/ssr: 19.2.16@angular/ssr: 18.2.21Workarounds
bootstrapfunctions.getPlatform()in application code.ngJitModeas false.References
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:L/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Angular: SSRF via protocol-relative and backslash URLs in Angular Platform-Server
CVE-2026-41423 / GHSA-45q2-gjvg-7973
More information
Details
Impact
A Server-Side Request Forgery (SSRF) vulnerability exists in
@angular/platform-serverdue to improper handling of URLs during Server-Side Rendering (SSR).When an attacker sends a request such as
GET /\evil.com/ HTTP/1.1the server engine (Express, etc.) passes the URL string to Angular’s rendering functions.Because the URL parser normalizes the backslash to a forward slash for HTTP/HTTPS schemes, the internal state of the application is hijacked to believe the current origin is
evil.com. This misinterpretation tricks the application into treating the attacker’s domain as the local origin. Consequently, any relativeHttpClientrequests orPlatformLocation.hostnamereferences are redirected to the attacker controlled server, potentially exposing internal APIs or metadata services.Affected APIs:
renderModulerenderApplicationCommonEngine(from@angular/ssr)Non-Affected APIs:
AngularAppEngine(from@angular/ssr)AngularNodeAppEngine(from@angular/ssr)Attack Preconditions
req.url).HttpClientwith relative URLs or usesPlatformLocation.hostnameto build URLs.Patches
Workarounds
Developers should implement a middleware to sanitize the request URL before it reaches Angular. This involves stripping or normalizing leading slashes:
References
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:L/SI:L/SA:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
Angular SSR: Global Platform Injector Race Condition Leads to Cross-Request Data Leakage
CVE-2025-59052 / GHSA-68x2-mx4q-78m7
More information
Details
Impact
Angular uses a DI container (the "platform injector") to hold request-specific state during server-side rendering. For historical reasons, the container was stored as a JavaScript module-scoped global variable. When multiple requests are processed concurrently, they could inadvertently share or overwrite the global injector state.
In practical terms, this can lead to one request responding with data meant for a completely different request, leaking data or tokens included on the rendered page or in response headers. As long as an attacker had network access to send any traffic that received a rendered response, they may have been able to send a large number of requests and then inspect the responses for information leaks.
The following APIs were vulnerable and required SSR-only breaking changes:
bootstrapApplication: This function previously implicitly retrieved the last platform injector that was created. It now requires an explicitBootstrapContextin a server environment. This function is only used for standalone applications. NgModule-based applications are not affected.getPlatform: This function previously returned the last platform instance that was created. It now always returnsnullin a server environment.destroyPlatform: This function previously destroyed the last platform instance that was created. It's now a no-op when called in a server environment.For
bootstrapApplication, the framework now provides a new argument to the application's bootstrap function:As is usually the case for changes to Angular, an automatic schematic will take care of these code changes as part of ng update:
The schematic can also be invoked explicitly if the version bump was pulled in independently:
For applications that still use
CommonEngine, thebootstrapproperty inCommonEngineOptionsalso gains the samecontextargument in the patched versions of Angular.In local development (
ng serve), Angular CLI triggered a codepath for Angular's "JIT" feature on the server even in applications that weren't using it in the browser. The codepath introduced async behavior between platform creation and application bootstrap, triggering the race condition even if an application didn't explicitly usegetPlatformor custom async logic inbootstrap. Angular applications should never run in this mode outside of local development.Patches
The issue has been patched in all active release lines as well as in the v21 prerelease:
@angular/platform-server: 21.0.0-next.3@angular/platform-server: 20.3.0@angular/platform-server: 19.2.15@angular/platform-server:18.2.14@angular/ssr: 21.0.0-next.3@angular/ssr: 20.3.0@angular/ssr: 19.2.16@angular/ssr: 18.2.21Workarounds
bootstrapfunctions.getPlatform()in application code.ngJitModeas false.References
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:L/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
@angular/platform-server: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
CVE-2026-50555 / GHSA-hqr9-c56f-3x7f
More information
Details
A Cross-Site Scripting (XSS) vulnerability exists in
@angular/platform-server's DOM emulation dependency (domino) when serializing the content of raw-text elements (such as<script>,<style>, and<iframe>).dominosupports escaping raw-text elements during serialization to prevent closing-tag breakout. However, a Unicode index alignment bug existed in this escaping logic.In JavaScript, string lengths and character indices are calculated based on UTF-16 code units (where astral characters—such as emojis—occupy 2 code units / 4 bytes). If the bound dynamic text contained astral Unicode characters before the closing tag (e.g.
</script>,</style>, or</iframe>), the index offset calculation indomino's replacement logic shifted.This misalignment caused
dominoto fail to replace or escape the closing tag, leaving it raw and unescaped in the output HTML.An attacker who controls the dynamic text can supply a payload containing both an astral Unicode character and a closing tag (e.g.,
😀</iframe><script>alert(1)</script>). When serialized on the server during SSR, the browser parses the unescaped closing tag, exits the raw-text context early, and executes the subsequent<script>block, leading to same-origin Cross-Site Scripting (XSS).Impact
This vulnerability allows an attacker to perform same-origin Cross-Site Scripting (XSS) attacks against any user visiting an SSR-rendered page that binds user-controlled data inside raw-text elements. This can lead to session hijacking, credentials theft, unauthorized actions on behalf of users, and defacement.
Patched Versions
Workarounds
If you cannot immediately update your dependencies, you can:
<iframe>or other raw-text elements.Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
@angular/platform-server: SSRF via Hostname Hijacking
CVE-2026-46417 / GHSA-rfh7-fxqc-q52v
More information
Details
Impact
A Server-Side Request Forgery (SSRF) vulnerability exists in
@angular/platform-server. The issue stems from how the server-side rendering (SSR) engine processes the request URL provided to the rendering entry points.When an absolute-form URL (e.g.,
http://evil.com) is passed to the rendering engine, the internalServerPlatformLocationcan be manipulated into adopting the attacker-controlled domain as the "current" hostname.Consequently, any relative
HttpClientrequests orPlatformLocation.hostnamereferences are redirected to the attacker controlled server, potentially exposing internal APIs or metadata services.Fix Information
The vulnerability is mitigated by introducing an Allowlist Mechanism directly into the core rendering APIs.
The renderModule and renderApplication functions now include an allowedHosts configuration option. The rendering engine validates the hostname extracted from the request URL against this list before proceeding. If the hostname does not match an allowed entry, the engine prevents the hostname hijacking, ensuring that HttpClient requests remain restricted to trusted domains.
Patches
Workarounds
Developers unable to update immediately should implement strict URL validation in their server entry point (e.g.,
server.ts). Ensure thatreq.urlis validated against a known list of trusted hostnames or normalized to a relative path before being passed torenderApplicationorrenderModule.Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:L/SI:L/SA:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
@angular/platform-server: URL Parser Differential leading to SSRF Allowlist Bypass
CVE-2026-50168 / GHSA-xrxm-cp7j-8xf6
More information
Details
An issue in the
@angular/platform-serverpackage allows remote attackers to bypass host allowlist constraints and direct server-side outgoing requests to arbitrary external endpoints. This occurs due to a parser differential between the strict WHATWG URL parser used for allowlist validation and the lenient Domino URL parser used to initialize the server emulated DOM.When a server-side request contains a malformed URL with a double port structure (e.g.,
http://evil.com:80:80/path), Node's strictURL.canParse(url)logic returnsfalseand skips host check validation entirely. However, the same malformed URL is later accepted and parsed leniently by Domino's internal parser, which resolves the origin tohttp://evil.com:80. The Angular SSR HTTP request interceptor (relativeUrlsTransformerInterceptorFn) then resolves all relative backend HTTP requests against this adopted origin, executing the SSRF attack.Impact
Any Angular application utilizing server-side rendering (
@angular/platform-server) that configures host routing allowlists (allowedHosts) is vulnerable to this allowlist bypass.By sending an HTTP request with a malformed Host header (e.g.
Host: evil.com:80:80) or an absolute-form request URI, an attacker can bypass the allowlist logic completely (even when configured with a strict default deny setup). The SSR application will then route all relativeHttpClientoutgoing API queries—which commonly carry sensitive credentials, session cookies, and internal authorization tokens—to the attacker-controlled server instead of the intended backend services. Additionally, the attacker can supply custom payloads back to the emulated DOM, leading to response injection and content poisoning within the rendered HTML served to users.Attack Preconditions
To successfully exploit this vulnerability, the following environment parameters and application states must all concurrently exist:
@angular/platform-server).config.urlto the rendering API (renderApplicationorrenderModule).this.http.get('/api/data')) that undergo base-URL interceptor rewriting.allowedHostsoptions to limit valid server locations.Patches
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
Angular SSR: Missing Fallback Raw-Content Serialization Escaping leads to Cross-Site Scripting (XSS)
CVE-2026-69149 / GHSA-vpx6-8pjr-4g3v
More information
Details
A Cross-Site Scripting (XSS) vulnerability exists in
@angular/platform-server's DOM emulation dependency (domino) when serializing the content of fallback raw-content elements (<iframe>,<noembed>,<noframes>, and<noscript>).When rendering dynamic text content inside fallback raw-content elements via template bindings, the template engine expects the browser to render the content safely. Under Server-Side Rendering (SSR),
dominois configured with scripting enabled, meaning these elements are treated as raw-text elements.However,
domino's serializer previously did not escape text nodes within fallback raw-content elements (<iframe>,<noembed>,<noframes>,<noscript>) during DOM serialization. As a result, any occurrence of closing tags in the bound dynamic text was not escaped.The unescaped closing tag could be serialized directly into the output HTML. When parsed by a browser or re-parsed during SSR post-processing without preserving raw-content parser state, an injected closing tag closes the element early, allowing an injected script block to execute in the user's browser context, causing same-origin Cross-Site Scripting (XSS).
Impact
This vulnerability allows an attacker to perform same-origin Cross-Site Scripting (XSS) attacks against any user visiting an SSR-rendered page that binds user-controlled data inside fallback raw-content elements (
<iframe>,<noembed>,<noframes>,<noscript>). This can lead to session hijacking, credentials theft, unauthorized actions on behalf of users, and defacement.Patched Versions
Workarounds
If you cannot immediately update your dependencies, you can mitigate this issue using any of the following approaches:
domino. Disabling this step preventsdominofrom re-parsing and re-serializing the HTML during server-side rendering.angular.json, setinlineCriticaltofalseunder style optimization options:{ "projects": { "my-app": { "architect": { "build": { "builder": "@angular/build:application", "options": { "optimization": { "styles": { "inlineCritical": false } } } } } } } }CommonEngine, setinlineCriticalCss: falsein your render options.<iframe>,<noembed>,<noframes>,<noscript>).Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
Release Notes
angular/angular (@angular/platform-server)
v20.0.0Compare Source
Blog post: https://blog.angular.dev/announcing-angular-v20-b5c9c06cf301
Breaking Changes
common
Yformatter (week-numbering year) without also includingw(week number) is now detected as suspicious date pattern, asyis typically intended.AsyncPipenow directly catches unhandled errors insubscriptions and promises and reports them to the application's
ErrorHandler. For Zone-based applications, these errors would havebeen caught by ZoneJS and reported to
ErrorHandlerso the result isgenerally the same. The change to the exact mechanism for reporting can
result in differences in test environments that will require test
updates.
compiler
'in' in an expression now refers to the operator
voidin an expression now refers to the operatorPreviously an expression in the template like
{{void}}referred to aproperty on the component class. After this change it now refers to the
voidoperator, which would make the above example invalid. If you haveexisting expressions that need to refer to a property named
void,change the expression to use
this.voidinstead:{{this.void}}.Parenthesis are always respected.
This can lead to runtime breakages when a nullish coalescing operator is nested within parentheses.
eg.
{{ (foo?.bar).baz }}will throw iffoois nullish. This is the same behavior as native JavaScript.core
TypeScript versions less than 5.8 are no longer supported.
the
TestBed.flushEffects()was removed - usethe
TestBed.tick()instead.provideExperimentalCheckNoChangesForDebughas severalbreaking changes:
provideCheckNoChangesConfiguseNgZoneOnStableoption is removed. This wasn't found to be generallymore useful than
intervalprovideExperimentalZonelessChangeDetectionisrenamed to
provideZonelessChangeDetectionas it is now "DeveloperPreview" rather than "Experimental".
InjectFlagshas been removed.injectno longer acceptsInjectFlags.Injector.getno longer acceptsInjectFlags.EnvironmentInjector.getno longer acceptsInjectFlags.TestBed.getno longer acceptsInjectFlags.TestBed.injectno longer acceptsInjectFlags.TestBed.gethas been removed. UseTestBed.injectinstead.afterRender was renamed to afterEveryRender.
Before upgrading to Angular v20, ensure the Node.js version is at least 20.11.1.
For the full list of supported versions, visit: https://angular.dev/reference/versions
PendingTasks.runno longer returns the result of theasync function. If this behavior is desired, it can be re-implemented
manually with the
PendingTasks.add. Be aware, however, that promise rejectionswill need to be handled or they can cause the node process to shut down
when using SSR.
Uncaught errors in listeners which were previously only reported to
ErrorHandlerare now also reported to Angular's internal errorhandling machinery. For tests, this means that the error will be
rethrown by default rather than only logging the error. Developers
should fix these errors, catch them in the test if the test is
intentionally covering an error case, or use
rethrowApplicationErrors: falseinconfigureTestingModuleas a last resort.The
anyoverload has been removed frominjector.get. It now only supportsProviderToken<T>and (deprecatedsince v4)
string.Animations are guaranteed to be flushed when Angular
runs automatic change detection or manual calls to
ApplicationRef.tick.Prior to this change, animations would not be flushed in some situations
if change detection did not run on any views attached to the
application. This change can affect tests which may rely on the old
behavior, often by making assertions on DOM elements that should have
been removed but weren't because DOM removal is delayed until animations
are flushed.
ApplicationRef.tickwill no longer catch and reporterrors to the application
ErrorHandler. Errors will instead be thrown out ofthe method and will allow callers to determine how to handle these
errors, such as aborting follow-up work or reporting the error and
continuing.
This commit deprecates
ng-reflect-*attributes and updates the runtime to stop producing them by default. Please refactor application and test code to avoid relying onng-reflect-*attributes.To enable a more seamless upgrade to v20, we've added the
provideNgReflectAttributes()function (can be imported from the@angular/corepackage), which enables the mode in which Angular would be producing those attribites (in dev mode only). You can add theprovideNgReflectAttributes()function to the list of providers within the bootstrap call.router
RedirectFncan now returnObservableorPromise. Any code that directly calls functions returning this typemay need to be adjusted to account for this.
required writable arrays have now been updated to accept readonly
arrays when no mutations are done.
Routeno longer includeanyinthe type union. The union includes functions for the functional guards
as well as a type matching
Injector.get:ProviderToken<T>|string.Note that string is still deprecated on both the route guards and
Injector.get.Deprecations
core
ngIf/ngFor/ngSwitchare deprecated. Use the control flow blocks instead (@for/@if/@switch).platform-browser
@angular/platform-browser-dynamicplatform-server
@angular/platform-server/testingUse e2e tests to verify SSR behavior instead.
common
updateLatestValueif view is destroyed before promise resolves (#58041)NgOptimizedImageexceeds the preload limit (#60879)compiler
@forblocks (#60495)inkeyword in Binary expression (#58432)compiler-cli
core
Injector.destroyonInjectorcreated withInjector.create(#60054)toObservableas stable (#60449)provideExperimentalCheckNoChangesForDebugtoprovideCheckNoChangesConfig(#60906)PendingTasks.run(#60044)withEventReplay()is invoked (#61077)Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.