Skip to content

chore(deps): update dependency @angular/ssr to v21.2.9 [security]#423

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/npm-angular-ssr-vulnerability
Open

chore(deps): update dependency @angular/ssr to v21.2.9 [security]#423
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/npm-angular-ssr-vulnerability

Conversation

@renovate
Copy link
Copy Markdown
Contributor

@renovate renovate Bot commented Mar 19, 2026

This PR contains the following updates:

Package Change Age Confidence
@angular/ssr 21.2.021.2.9 age confidence
@angular/ssr 21.0.021.2.9 age confidence

Angular SSR has an Open Redirect via X-Forwarded-Prefix

CVE-2026-27738 / GHSA-xh43-g2fq-wjrj

More information

Details

An Open Redirect vulnerability exists in the internal URL processing logic in Angular SSR. The logic normalizes URL segments by stripping leading slashes; however, it only removes a single leading slash.

When an Angular SSR application is deployed behind a proxy that passes the X-Forwarded-Prefix header, an attacker can provide a value starting with three slashes (e.g., ///evil.com).

  1. The application processes a redirect (e.g., from a router redirectTo or i18n locale switch).
  2. Angular receives ///evil.com as the prefix.
  3. It strips one slash, leaving //evil.com.
  4. The resulting string is used in the Location header.
  5. Modern browsers interpret // as a protocol-relative URL, redirecting the user from https://your-app.com to https://evil.com.
Impact

This vulnerability allows attackers to conduct large-scale phishing and SEO hijacking:

  • Scale: A single request can poison a high-traffic route, impacting all users until the cache expires.
  • SEO Poisoning: Search engine crawlers may follow and index these malicious redirects, causing the legitimate site to be delisted or associated with malicious domains.
  • Trust: Because the initial URL belongs to the trusted domain, users and security tools are less likely to flag the redirect as malicious.
Attack Preconditions
  • The application must use Angular SSR.
  • The application must have routes that perform internal redirects.
  • The infrastructure (Reverse Proxy/CDN) must pass the X-Forwarded-Prefix header to the SSR process without sanitization.
  • The cache must not vary on the X-Forwarded-Prefix header.
Patches
  • 21.2.0-rc.1
  • 21.1.5
  • 20.3.17
  • 19.2.21
Workarounds

Until the patch is applied, developers should sanitize the X-Forwarded-Prefix header in theirserver.ts before the Angular engine processes the request:

app.use((req, res, next) => {
  const prefix = req.headers['x-forwarded-prefix']?.trim();
  if (prefix) {
    // Sanitize by removing all leading slashes
    req.headers['x-forwarded-prefix'] = prefix.replace(/^[/\\]+/, '/');
  }
  next();
});
Resources

Severity

  • CVSS Score: 6.9 / 10 (Medium)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Angular SSR is vulnerable to SSRF and Header Injection via request handling pipeline

CVE-2026-27739 / GHSA-x288-3778-4hhx

More information

Details

A Server-Side Request Forgery (SSRF) vulnerability has been identified in the Angular SSR request handling pipeline. The vulnerability exists because Angular’s internal URL reconstruction logic directly trusts and consumes user-controlled HTTP headers specifically the Host and X-Forwarded-* family to determine the application's base origin without any validation of the destination domain.

Specifically, the framework didn't have checks for the following:

  • Host Domain: The Host and X-Forwarded-Host headers were not checked to belong to a trusted origin. This allows an attacker to redefine the "base" of the application to an arbitrary external domain.
  • Path & Character Sanitization: The X-Forwarded-Host header was not checked for path segments or special characters, allowing manipulation of the base path for all resolved relative URLs.
  • Port Validation: The X-Forwarded-Port header was not verified as numeric, leading to malformed URI construction or injection attacks.

This vulnerability manifests in two primary ways:

  • Implicit Relative URL Resolution: Angular's HttpClient resolves relative URLs against this unvalidated and potentially malformed base origin. An attacker can "steer" these requests to an external server or internal service.
  • Explicit Manual Construction: Developers injecting the REQUEST object to manually construct URLs (for fetch or third-party SDKs) directly inherit these unsanitized values. By accessing the Host / X-Forwarded-* headers, the application logic may perform requests to attacker-controlled destinations or malformed endpoints.
Impact

When successfully exploited, this vulnerability allows for arbitrary internal request steering. This can lead to:

  • Credential Exfiltration: Stealing sensitive Authorization headers or session cookies by redirecting them to an attacker's server.
  • Internal Network Probing: Accessing and transmitting data from internal services, databases, or cloud metadata endpoints (e.g., 169.254.169.254) not exposed to the public internet.
  • Confidentiality Breach: Accessing sensitive information processed within the application's server-side context.
Attack Preconditions
  • The victim application must use Angular SSR (Server-Side Rendering).
  • The application must perform HttpClient requests using relative URLs OR manually construct URLs using the unvalidated Host / X-Forwarded-* headers using the REQUEST object.
  • Direct Header Access: The application server is reachable by an attacker who can influence these headers without strict validation from a front-facing proxy.
  • Lack of Upstream Validation: The infrastructure (Cloud, CDN, or Load Balancer) does not sanitize or validate incoming headers.
Patches
  • 21.2.0-rc.1
  • 21.1.5
  • 20.3.17
  • 19.2.21
Workarounds
  • Use Absolute URLs: Avoid using req.headers for URL construction. Instead, use trusted variables for your base API paths.
  • Implement Strict Header Validation (Middleware): If you cannot upgrade immediately, implement a middleware in your server.ts to enforce numeric ports and validated hostnames.
const ALLOWED_HOSTS = new Set(['your-domain.com']);

app.use((req, res, next) => {
  const hostHeader = (req.headers['x-forwarded-host'] ?? req.headers['host'])?.toString();
  const portHeader = req.headers['x-forwarded-port']?.toString();

  if (hostHeader) {
    const hostname = hostHeader.split(':')[0];
    // Reject if hostname contains path separators or is not in allowlist
    if (/^[a-z0-9.:-]+$/i.test(hostname) || 
       (!ALLOWED_HOSTS.has(hostname) && hostname !== 'localhost')) {
      return res.status(400).send('Invalid Hostname');
    }
  }

  // Ensure port is strictly numeric if provided
  if (portHeader && !/^\d+$/.test(portHeader)) {
    return res.status(400).send('Invalid Port');
  }

  next();
});
References

Severity

  • CVSS Score: 9.2 / 10 (Critical)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:H/SI:L/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Protocol-Relative URL Injection via Single Backslash Bypass in Angular SSR

CVE-2026-33397 / GHSA-vfx2-hv2g-xj5f

More information

Details

An Open Redirect vulnerability exists in @angular/ssr due to an incomplete fix for CVE-2026-27738. While the original fix successfully blocked multiple leading slashes (e.g., ///), the internal validation logic fails to account for a single backslash (\) bypass.

When an Angular SSR application is deployed behind a proxy that passes the X-Forwarded-Prefix header:

  • An attacker provides a value starting with a single backslash (e.g., \evil.com).
  • The internal validation failed to flag the single backslash as invalid.
  • The application prepends a leading forward slash, resulting in a Location header containing /\evil.com.
  • Modern browsers interpret the /\ sequence as //, treating it as a protocol-relative URL and redirecting the user to the attacker-controlled domain.

Furthermore, the response lacks the Vary: X-Forwarded-Prefix header, allowing the malicious redirect to be stored in intermediate caches (Web Cache Poisoning).

Impact

This vulnerability allows attackers to conduct large-scale phishing and SEO hijacking:

  • Scale: A single request can poison a high-traffic route, impacting all users until the cache expires.
  • SEO Poisoning: Search engine crawlers may follow and index these malicious redirects, causing the legitimate site to be delisted or associated with malicious domains.
  • Trust: Because the initial URL belongs to the trusted domain, users and security tools are less likely to flag the redirect as malicious.
Patches
  • 22.0.0-next.2
  • 21.2.3
  • 20.3.21
Workarounds

Until the patch is applied, developers should sanitize the X-Forwarded-Prefix header in their server.ts before the Angular engine processes the request:

app.use((req, res, next) => {
  const prefix = req.headers['x-forwarded-prefix'];
  if (typeof prefix === 'string') {
    // Sanitize by removing all leading forward and backward slashes
    req.headers['x-forwarded-prefix'] = prefix.trim().replace(/^[/\\]+/, '/');
  }
  next();
});
References

Severity

  • CVSS Score: 6.9 / 10 (Medium)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Angular SSR has Open Redirect and Request Steering via Encoded X-Forwarded-Prefix

CVE-2026-44437 / GHSA-69xr-m8h6-h664

More information

Details

Description

A vulnerability exists in the X-Forwarded-Prefix header processing logic within Angular SSR. The internal validation mechanism fails to properly account for URL-encoded characters, specifically dots (%2e%2e). This allows an attacker to bypass security filters by injecting encoded path traversal sequences that are later decoded and utilized by the application logic.
When an Angular SSR application is configured to trust proxy headers and is deployed behind a proxy that forwards the X-Forwarded-Prefix header without prior sanitization, an attacker can provide a payload such as /%2e%2e/evil.

The vulnerability manifests in two ways:

  • Open Redirect: The application processes a redirect (e.g., router redirectTo). The decoded traversal payload manipulates the Location header, forcing the browser to an unintended path or external domain.
  • Server-Side Request Steering: The manipulated prefix is used as the base path for server-side HttpClient requests. This causes the server to make requests to unintended internal paths or external endpoints.
Attack Preconditions
  • The application must use Angular SSR.
  • The application must perform internal redirects or use relative URLs in server-side HttpClient requests.
  • The upstream infrastructure (Reverse Proxy/CDN) must pass the X-Forwarded-Prefix header to the SSR process without stripping or sanitizing it.
Workarounds

Until the patch is applied, developers should manually sanitize the X-Forwarded-Prefix header in their server.ts. The workaround involves decoding the component to catch encoded traversal attempts before normalization:

app.use((req, res, next) => {
  let prefix = req.headers['x-forwarded-prefix'];
  if (Array.isArray(prefix)) prefix = prefix[0];

  if (prefix) {
    try {
      // Decode the prefix to catch encoded characters like %2e (dots)
      const decodedPrefix = decodeURIComponent(prefix);
      
      // Sanitize: remove traversal attempts and ensure a safe leading slash
      req.headers['x-forwarded-prefix'] = decodedPrefix
        .replace(/\.\./g, '')       // Remove any dot-dot sequences
        .replace(/^[/\\]+/, '/');   // Ensure it starts with exactly one slash
    } catch (e) {
      // If decoding fails, remove the potentially malicious header entirely
      delete req.headers['x-forwarded-prefix'];
    }
  }
  next();
});
Configuring Trusted Proxy Headers

By default, Angular ignores all X-Forwarded-* headers. If your application is behind a trusted reverse proxy (like a load balancer) that sets these headers, you can configure Angular to trust them.
You can configure trustProxyHeaders when initializing the application engine:

const appEngine = new AngularAppEngine({
  // Trust specific headers
  trustProxyHeaders: ['x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-prefix'], 
});

const nodeAppEngine = new AngularNodeAppEngine({
  // Trust all X-Forwarded-* headers
  trustProxyHeaders: true, 
});
Patches
  • 22.0.0-next.7
  • 21.2.9
  • 20.3.25
  • 19.2.25
Resources

Severity

  • CVSS Score: 6.9 / 10 (Medium)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:L/SI:L/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

angular/angular-cli (@​angular/ssr)

v21.2.9

Compare Source

@​angular/cli
Commit Type Description
233deef01 fix fix broken img ref in ai-tutor
7cea9885c fix introduce initial package manager workspace awareness
5b1a5b743 fix remove standalone true ref in ai tutor
@​schematics/angular
Commit Type Description
e7abeb5c7 fix add missing imports for focus and skip APIs in refactor-jasmine-vitest
@​angular/ssr
Commit Type Description
94023f62c fix introduce trustProxyHeaders option to safely validate and sanitize proxy headers
5ffe5c309 fix add support for configuring trusted proxy headers via environment variable
930ada9b7 fix decode route segments when building and matching route tree
0dc8a440c fix use router to normalize URLs for comparison

v21.2.8: 21.2.8

Compare Source

@​angular/cli
Commit Description
fix - e91280c05 dynamically resolve project Angular CLI executable inside MCP tools
fix - 01af6741b ignore EBADF file system errors during MCP project scan
fix - f7a3e6ed8 use headless option in MCP test tool
@​angular-devkit/build-angular
Commit Description
fix - 00336c037 ensure route has leading slash in prerender builder
fix - e87d302d6 fix app-shell route format and
@​angular/build
Commit Description
fix - c93140a54 use rootDir for HMR component updates path resolution
fix - 6df2b1488 validate V8 coverage support for browsers in Vitest

v21.2.7

Compare Source

@​angular/cli
Commit Type Description
971041aa1 fix handle missing package manager during analytics initialization
@​angular/build
Commit Type Description
365cce81d fix preserve coverage ignore comments in development
9f74660c3 fix show clear error when styleUrl points to a TypeScript file

v21.2.6

Compare Source

@​angular/cli
Commit Type Description
ea14f28cc fix fix sourceRoot resolution for MCP projects tool
@​angular/build
Commit Type Description
9136eb376 fix ensure transitive SCSS partial errors are tracked in watch mode
8186faa11 fix ensure Vitest mock patching is executed only once
107d1a9e2 fix preserve error stack traces during prerendering
b7f457253 fix scope CHROME_BIN executable path to individual playwright instances

v21.2.5

Compare Source

@​angular/cli
Commit Type Description
cadf9b201 feat support custom port in MCP devserver start tool
@​angular/ssr
Commit Type Description
bbc255419 fix allow underscores in host validation
b1fe66a7f fix patch Headers.forEach in cloneRequestAndPatchHeaders

v21.2.4

Compare Source

@​angular/cli
Commit Type Description
a7787d092 fix restore console methods after logger completes
@​angular/build
Commit Type Description
7170599ab fix deduplicate and merge coverage excludes with vitest
c73f13797 fix prevent reporter duplicates by explicitly overriding Vitest configuration
956ccaa71 fix remove default for unit-test coverage option
36978db7e fix warn about performance of test.exclude in vitest configuration
6ec36f5be fix warn when vitest watch config conflicts with builder
@​angular/ssr
Commit Type Description
9bdf782c8 fix apply forwarded prefix and vary header in accept-language redirects
628c58672 fix support '*' in allowedHosts and warn about security risks

v21.2.3

Compare Source

@​angular/cli
Commit Type Description
1505164bb fix use parsed package name for migrate-only updates
@​angular/build
Commit Type Description
75fa94cad fix alias createRequire banner import to avoid duplicate binding
d009aa1ec fix only use external packages for polyfills when no local files are present
@​angular/ssr
Commit Type Description
f3e0e82c2 fix disallow x-forwarded-prefix starting with a backslash
b8bcd59b4 fix ensure unique values in redirect response Vary header
84385411d fix support custom headers in redirect responses

v21.2.2

Compare Source

@​angular/cli
Commit Type Description
8447d9132 fix conditionally quote package names when adding dependencies based on host requirements
d2f209823 fix preserve exact version in ng add when requested
28f4d684a perf avoid redundant package version resolution in ng add
@​angular/build
Commit Type Description
06010294f fix allow any CHROME_BIN for vitest playwright provider
8dec0c62b fix normalize line endings for CSP hash generation
58688ebd7 fix pass process environment variables to prerender workers
4ca61647f fix resolve assets correctly during i18n prerendering

v21.2.1

Compare Source

@​angular/cli
Commit Type Description
ae4c28d00 fix correct dev dependency detection logic in ng add
465073bc1 fix disable npm update notifier in package manager host
36270634f fix ensure group members are updated to targeted version
d87dba6af fix ignore unknown files when formatting schematic changes
@​schematics/angular
Commit Type Description
72d466aa0 fix prevent adding test dependencies when minimal option is enabled
@​angular-devkit/build-angular
Commit Type Description
0019d1c8e fix update copy-webpack-plugin to v14.0.0
@​angular/build
Commit Type Description
6ad860863 fix bundle polyfills to preserve execution order in dev server
d17397375 fix conditionally allow vi.mock for non-relative imports
0d49f86ed fix resolve style include paths relative to ng-package.json in unit-test builder
584f6a2d9 fix treat empty browsers array as undefined in unit-test builder
6699cdc9b perf fix memory leak in ng serve with i18n
@​angular/ssr
Commit Type Description
43a9dfa66 fix improve header validation logic
dee3717b3 fix introduce DI token to signal route discovery process

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • ""
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 19, 2026

Deploy Preview for angular-runtime-demo failed. Why did it fail? →

Name Link
🔨 Latest commit f89fccc
🔍 Latest deploy log https://app.netlify.com/projects/angular-runtime-demo/deploys/69bc75e39046260008fcc596

@github-actions github-actions Bot added the type: chore work needed to keep the product and development running smoothly label Mar 19, 2026
kodiakhq[bot]
kodiakhq Bot previously approved these changes Mar 19, 2026
@renovate renovate Bot changed the title chore(deps): update dependency @angular/ssr to v21.2.3 [security] chore(deps): update dependency @angular/ssr to v21.2.3 [security] - autoclosed Mar 27, 2026
@renovate renovate Bot closed this Mar 27, 2026
@renovate renovate Bot deleted the renovate/npm-angular-ssr-vulnerability branch March 27, 2026 03:00
@renovate renovate Bot changed the title chore(deps): update dependency @angular/ssr to v21.2.3 [security] - autoclosed chore(deps): update dependency @angular/ssr to v21.2.3 [security] Mar 30, 2026
@renovate renovate Bot reopened this Mar 30, 2026
@renovate renovate Bot force-pushed the renovate/npm-angular-ssr-vulnerability branch 2 times, most recently from f89fccc to 44e3ee5 Compare March 30, 2026 19:19
@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 30, 2026

Deploy Preview for angular-runtime-demo failed. Why did it fail? →

Name Link
🔨 Latest commit 44e3ee5
🔍 Latest deploy log https://app.netlify.com/projects/angular-runtime-demo/deploys/69caccd2a32a0f00084ca441

@renovate renovate Bot force-pushed the renovate/npm-angular-ssr-vulnerability branch from 44e3ee5 to 64f3644 Compare April 15, 2026 13:52
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 15, 2026

Deploy Preview for angular-runtime-demo failed. Why did it fail? →

Name Link
🔨 Latest commit 64f3644
🔍 Latest deploy log https://app.netlify.com/projects/angular-runtime-demo/deploys/69df9838bae1ae00091453bf

kodiakhq[bot]
kodiakhq Bot previously approved these changes Apr 15, 2026
@renovate renovate Bot changed the title chore(deps): update dependency @angular/ssr to v21.2.3 [security] chore(deps): update dependency @angular/ssr to v21.2.3 [security] - autoclosed Apr 27, 2026
@renovate renovate Bot closed this Apr 27, 2026
@renovate renovate Bot changed the title chore(deps): update dependency @angular/ssr to v21.2.3 [security] - autoclosed chore(deps): update dependency @angular/ssr to v21.2.3 [security] Apr 28, 2026
@renovate renovate Bot reopened this Apr 28, 2026
@renovate renovate Bot force-pushed the renovate/npm-angular-ssr-vulnerability branch 2 times, most recently from 64f3644 to db14b9b Compare April 28, 2026 00:57
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 28, 2026

Deploy Preview for angular-runtime-demo failed. Why did it fail? →

Name Link
🔨 Latest commit 0fe36a8
🔍 Latest deploy log https://app.netlify.com/projects/angular-runtime-demo/deploys/69fe044eba5fdc0008f8fbd5

@renovate renovate Bot force-pushed the renovate/npm-angular-ssr-vulnerability branch from db14b9b to 0fe36a8 Compare May 8, 2026 15:42
@renovate renovate Bot changed the title chore(deps): update dependency @angular/ssr to v21.2.3 [security] chore(deps): update dependency @angular/ssr to v21.2.9 [security] May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bump-framework-in-fixtures dependencies javascript type: chore work needed to keep the product and development running smoothly

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants