15482 Commits

Author SHA1 Message Date
Alan Agius 1881ede3a7 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.
(cherry picked from commit 8446e46f8b)
2026-06-09 16:54:21 +00:00
Matthew Beck 96b6419d95 ci: run benchmark comparison in isolated worktree and harden security
- Run comparison benchmark in an isolated git worktree to prevent workspace pollution and local branch conflicts.
- Harden security by passing benchmark target and SHA as environment variables to prevent shell injection, and adding '--' to bazel query and git rev-parse.
- Optimize workflow by removing pnpm caching to mitigate cache poisoning risks.
- Improve robustness of benchmark log parsing, supporting both ZIP outputs and raw directories, and safely checking for JSON reports.
- Centralize git command execution on the dev-infra GitClient for consistency.
- Add tslib to benchpress dependencies to prevent module resolution failures.

(cherry picked from commit 547d85addf)
2026-06-09 16:48:55 +00:00
SkyZeroZx 4254eb416c fix(http): preserve empty referrer option in HttpRequest
Preserve `referrer: ''` when constructing and cloning HttpRequest.

An empty string is a valid Fetch referrer value and is documented by
Angular as the way to omit referrer information for sensitive requests.
The previous truthy checks treated it as if the option was not provided,
causing requests to fall back to the browser default referrer behavior.

(cherry picked from commit cd771d3712)
2026-06-09 16:41:24 +00:00
SkyZeroZx cf97b1f828 fix(service-worker): Strips sensitive headers on cross-origin redirects
Removes `Authorization`, `Cookie`, and `Proxy-Authorization` headers when a request is redirected to a different origin. This aligns with the Fetch API's redirect algorithm to prevent sensitive information from being sent to third-party origins.

(cherry picked from commit 47d68dcb26)
2026-06-08 21:49:34 +00:00
SkyZeroZx 167bd4c162 fix(http): Rejects non-HTTP(S) URLs in JSONP requests
Prevents JSONP requests from using URLs with unsupported protocols for improved security.

Fixes #68832

(cherry picked from commit 231eff19a1)
2026-06-08 13:56:46 -07:00
SkyZeroZx 393b84caf8 fix(compiler): sanitize two-way properties
Apply schema-derived sanitizer resolution to TwoWayProperty ops so native two-way DOM bindings emit the same sanitizer as one-way property bindings.

Add compiler compliance coverage for innerHTML, srcdoc, URL, resource URL, and security-sensitive attribute cases.

(cherry picked from commit 3c70270c96)
2026-06-08 20:12:27 +00:00
arturovt d4e08da89d refactor(core): convert LocaleDataIndex from enum to const object
TypeScript enums compile to self-executing function expressions that
are not tree-shakable, even when unused. Replace LocaleDataIndex with
a plain const object using `as const` to produce the same numeric
indices and literal types without the IIFE side-effect.

(cherry picked from commit d3239a3ac2)
2026-06-05 18:10:47 +00:00
SkyZeroZx dfff57ede9 fix(common): Limits date format string length
Introduces a maximum length of 256 characters for date format strings.

This prevents potential Denial of Service (DoS) attacks by throwing an
`INVALID_DATE_FORMAT` error if an excessively long format string is
provided to `formatDate` or `DatePipe`, safeguarding against performance
degradation or application crashes.

(cherry picked from commit eeb03f4ea3)
2026-06-05 17:58:41 +00:00
Alan Agius ed48ca7f51 fix(platform-server): harden platform location origin validation during SSR
Add allowOriginChange option to ResolveUrlOptions in resolveUrl to enforce same-origin validation on resolved URLs. When set to false, it prevents any cross-origin changes (including HTTP/HTTPS URLs), aligning the emulated server-side platform location environment with browser security behavior.

Refactor ServerPlatformLocation.replaceState to use allowOriginChange: false instead of manual comparison, hardening state change validation against cross-origin URLs.

Add unit tests in url_spec.ts and platform_location_spec.ts for the origin validation changes.
2026-06-05 10:44:20 -07:00
Alan Agius feb040043d refactor(platform-server): replace standard Error with RuntimeError
Update platform-server to use Angular 's native `RuntimeError` class.
This aligns error throwing patterns in platform-server with other packages of the framework such as core, common, and platform-browser.

For URL and host errors, the error messages are configured to return only the raw dynamic URL when `ngDevMode` is false (in production) to aid in troubleshooting without bloating production bundles.
2026-06-05 10:44:20 -07:00
Alan Agius 1d87c49f6e fix(common): use cryptographically secure SHA-256 for transfer cache key generation
Replace the custom 64-bit non-cryptographic combined DJB2 hashing implementation in HttpTransferCache with a robust, pure JavaScript, synchronous SHA-256 algorithm.

Using DJB2 is vulnerable to pre-image and second-preimage attacks due to its small 64-bit keyspace and mathematical simplicity. An attacker could craft colliding request inputs to poison the cache, potentially causing a CDN or the application to serve the wrong cached response to legitimate users.

SHA-256 provides strong cryptographic collision resistance, preventing cache key collision attacks. A custom synchronous implementation is required because the Web Crypto API (`crypto.subtle.digest`) is asynchronous, whereas the transfer cache state lookup and interceptor flow must operate synchronously.

Also, update the unit tests to dynamically verify the custom SHA-256 output against the native Web Crypto API.
2026-06-05 10:40:20 -07:00
Doug Parker 55b7b5a6b6 fix(forms): set additionalProperties: false on generated WebMCP form
This tells the agent that all input properties have been explicitly declared and that it should not attempt to specify additional arguments with unknown names. This provides a little more safety and gives the AI a little more information about the allowed set of inputs for this tool.

(cherry picked from commit df77e42327)
2026-06-04 21:18:10 +00:00
Matthieu Riegler ffb06c0514 fix(http): ensure query parameters are inserted before URL fragments
Previously, when making an HTTP request where the URL contained a fragment (`#`) and `HttpParams` were provided, the parameters were appended to the very end of the URL (after the fragment). This resulted in the parameters being treated as part of the fragment rather than query parameters, potentially bypassing server-side logic and validation.
This commit updates the URL parsing logic in `HttpRequest` to split the URL by the fragment, correctly inserting the query string before any fragment.

(cherry picked from commit cb8ceb1dde)
2026-06-04 21:02:04 +00:00
Stewart McGown e9fc72e16b test(core): add GC-based tests for signal graph prevConsumer leak fix (#68681)
Uses WeakRef + global.gc() to verify that destroyed effect consumers
become garbage-collectable when a non-live computed reads the same
producer.

The jasmine_test target is configured with node_options: --expose-gc.
GC tests are skipped in browser targets via isBrowser from
@angular/private/testing.

Made-with: Cursor

PR Close #68681
2026-06-04 19:25:37 +00:00
Stewart McGown 29fdb98684 fix(core): prevent dangling prevConsumer reference from leaking destroyed views (#68681)
When `producerAccessed` creates a new link for a non-live consumer (e.g.
a computed signal with no readers), it eagerly sets `prevConsumer` to the
producer's current `consumersTail`. However, because the consumer is not
live, `producerAddLiveConsumer` is skipped and the link is never inserted
into the producer's consumer doubly-linked list.

This means the link holds a reference *into* the producer's consumer list
without being *part* of it. When the node that `prevConsumer` points to is
later removed via `producerRemoveLiveConsumerLink`, the dangling link is
not patched because it isn't traversable from the list.

The result is that the removed consumer link — and everything it
references — is kept alive by the dangling `prevConsumer` pointer on the
non-live link, which itself is kept alive through the computed signal's
`producers` linked list.

In practice this causes multi-MB memory leaks in Angular apps: a
root-provided service with a computed signal (e.g. `AttachmentApiService.urls`)
holds a producer link to `ApplicationEnvironmentService.environmentSignal`.
That link's `prevConsumer` captures a stale reference to a destroyed view's
`ReactiveLViewConsumer` link, retaining the entire LView hierarchy —
components, QueryLists, ElementRefs, and detached DOM — after the view is
destroyed.

The fix initializes `prevConsumer` to `undefined` at link creation time.
This is safe because `producerAddLiveConsumer` unconditionally sets
`link.prevConsumer = consumersTail` (line 513) when the link is actually
inserted into the consumer list. The value set in `producerAccessed` was
always overwritten for live consumers, and was never correct for non-live
consumers.

Made-with: Cursor

PR Close #68681
2026-06-04 19:25:37 +00:00
Doug Parker 669146b0e7 fix(core): disable WebMCP during SSR
In certain scenarios like `provideExperimentalWebMcpTools` in `app.config.ts`, a WebMCP tool may be declared before SSR has a chance to polyfill Domino and trigger an error due to an `undefined` `document` value. This aborts from the process before WebMCP has a chance to crash.

(cherry picked from commit e50d47a493)
2026-06-04 18:44:33 +00:00
arturovt 3dd433b39a fix(core): use Object.hasOwn to handle null-prototype objects in toStylingKeyValueArray
Calling `.hasOwnProperty()` on an object created with `Object.create(null)`
throws a TypeError because such objects have no prototype and therefore no
inherited `hasOwnProperty` method. Replace it with `Object.hasOwn()`, which
is a static method immune to prototype chain issues.

Adds a regression test covering null-prototype objects passed to
`toStylingKeyValueArray`.

(cherry picked from commit a786862c54)
2026-06-04 18:37:48 +00:00
Matthieu Riegler 302cb601be refactor(core): Also throw an error on iframe attributes set to undefined
This is more a hardening concern. Other non-nullish values were already throwing but here we make it explicit that undefined also throws.

(cherry picked from commit c5293c4c9d)
2026-06-04 17:00:35 +00:00
Matthieu Riegler fa546f382d fix(core): harden TransferState restoration against DOM clobbering
Reject non-script elements when reading the SSR transfer state payload by id.
This prevents attacker-controlled elements with a clobbered id from spoofing
hydration state.

(cherry picked from commit 6bde84fa8e)
2026-06-03 23:03:01 +00:00
cexbrayat 3d9ca2f173 fix(compiler-cli): bind switch exhaustive check expressions
Ensure switch exhaustive check parameters are visited during template binding so local template symbols are resolved correctly.

This allows:

```html
@let state = this.state();
@switch (state.mode) {
  @case ('show') { {{ state.menu }}; }
  @case ('hide') {}
  @default never(state);
}
```

(cherry picked from commit e8430032e1)
2026-06-03 19:02:59 +00:00
Kristiyan Kostadinov a56f1cdf8f fix(compiler): more robust logic to check if regex can be optimized
Currently we only skip regex optimization if it has the `g` flag, however regexes can also have a state with the `y` flag.

These changes move to an allowlist model where we only optimize for a set of know flags.

(cherry picked from commit 636cc94105)
2026-06-03 18:53:41 +00:00
Angular Robot da07b3cbc7 build: update cross-repo angular dependencies
See associated pull request for more information.
2026-06-03 18:22:53 +02:00
Joey Perrott 31513301f2 release: bump version of in memory web api
(cherry picked from commit 09c03a2fe1)
2026-06-03 16:36:34 +02:00
Pawel Kozlowski 3ad9eb0217 Revert "fix(core): harden inherit definition feature against polluted prototypes"
This reverts commit f3c924926f.
2026-06-03 11:04:36 +02:00
Matthieu Riegler f3c924926f fix(core): harden inherit definition feature against polluted prototypes
Stop inheritance traversal before built-in prototype objects and only read `ɵcmp`/`ɵdir` when they are own properties of a super type. This prevents polluted inherited properties from being treated as Angular defs during inheritance merging.

Also adds regression tests covering polluted `Object.prototype.ɵdir` and `Object.prototype.ɵcmp` to ensure polluted host metadata is not inherited.

(cherry picked from commit e695379354)
2026-06-02 13:26:02 +02:00
Alan Agius 7b9130931d fix(platform-server): throw on suspicious URLs and restrict protocol-relative URLs
Currently, the platform-server attempts to neutralize URL hijacking and SSRF
bypasses by collapsing multiple leading slashes in relative paths. However,
sophisticated bypasses using obfuscated protocols (e.g., carriage returns or
newlines) or relative-like backslash paths can still lead to unexpected
origin takeovers.

This commit improves security by doing the following:
- Rejects protocol-relative URLs by throwing an error if they are not
  explicitly permitted via `allowProtocolRelative`.
- Strictly validates resolved URLs against the provided origin using
  `isSafeOriginChange`. If a URL unexpectedly shifts origins, an error
  is thrown.
- Permits origin changes only when standard absolute http/https protocols are
  explicitly declared in the input URL.

(cherry picked from commit 0b19c92d44)
2026-06-01 20:03:30 +02:00
Matthieu Riegler 9d9855a415 fix(migrations): Make the safe optional chaining idempotent
Our unit tests were missleading, the migration wasn't idempotent and `$safeNavigationMigration` were added multiple times on consecutive runs.

(cherry picked from commit 6038b9ede7)
2026-06-01 18:50:26 +02:00
Matthieu Riegler 5f14b82af8 refactor(core): Update webmcp support to use document.modelContext
The implementation in Chrome 150 moved `modelContext` from the navigator to the document (see webmachinelearning/webmcp/pull/184)

We're also removing the calls to the deprecated `unregisterTool` method.

fixes #68947

(cherry picked from commit 683172b39a)
2026-06-01 18:49:11 +02:00
Angular Robot 6fee7aaf89 build: update cross-repo angular dependencies
See associated pull request for more information.
2026-06-01 16:31:26 +02:00
Kristiyan Kostadinov 2891f7e787 fix(compiler): move projection attributes into constants
We can save some memory by moving the `attrs` passed into the `projection` instruction into the constant pool.

(cherry picked from commit f0b28f6443)
2026-06-01 12:28:36 +02:00
cexbrayat e81c7e8466 refactor(forms): type built-in getError results
Add overloads for built-in validation error keys so callers get precise error payload types from getError.

This enables signal forms template patterns like:

```html
@if (login.getError('minLength'); as minLengthError) {
  <div>Login should be {{ minLengthError.minLength }} characters</div>
}
```

(cherry picked from commit 45e8fb5d6c)
2026-05-29 14:58:47 +02:00
arturovt e3e25b5a53 fix(core): use Object.create(null) for LOCALE_DATA as a hardening measure
Prior to this commit, `LOCALE_DATA` was initialized as a plain object literal:

```typescript
let LOCALE_DATA: {[localeId: string]: any} = {};
```

While `__proto__` is neutralized by the `replace(/_/g, '-')` sanitization step (becoming `--proto--`), keys like `constructor` and `prototype` pass through unchanged and would modify special properties on `Object.prototype` if used as bracket notation keys on a plain object.

**Example attack through the public API:**

```typescript
// attacker calls the public registerLocaleData API with a crafted localeId
registerLocaleData(data, 'constructor');

// internally becomes:
LOCALE_DATA['constructor'] = data;
// → modifies Object.prototype.constructor for every object in the process

// or with extraData:
registerLocaleData(data, 'constructor', extraData);
// LOCALE_DATA['constructor'][LocaleDataIndex.ExtraData] = extraData;
// → Object.prototype[LocaleDataIndex.ExtraData] = extraData
// → every plain object in the process now has this property
// → affects JSON serialization, property enumeration, and framework internals

// consequence — any subsequent object created in the process is affected:
const user = getUserFromSession();
console.log(user[LocaleDataIndex.ExtraData]); // → attacker-controlled value
```

In a long-running SSR server this pollution persists for the lifetime of the process and affects all subsequent requests from all users.

**The fix** initializes `LOCALE_DATA` with `Object.create(null)`:

```typescript
let LOCALE_DATA: {[localeId: string]: any} = Object.create(null);
```

A null-prototype object has no prototype chain, so any key is treated as a plain string with no special behavior, making prototype pollution impossible regardless of input — without relying on the sanitization step as the sole protection.

(cherry picked from commit 0deac976f3)
2026-05-29 14:55:55 +02:00
arturovt 2d3db59321 fix(zone.js): validate __Zone_symbol_prefix to prevent DOM clobbering attacks
Previously, `__Zone_symbol_prefix` was read directly from `globalThis` without validating its type:

const symbolPrefix = global['__Zone_symbol_prefix'] || '__zone_symbol__';

This made it possible for DOM clobbering to interfere with Zone’s internal symbol handling. If an attacker injected a DOM element with the same name (for example via a form field or anchor ID), `global['__Zone_symbol_prefix']` could resolve to a DOM element instead of a string. Because DOM elements are truthy, the fallback would not be used, and Zone would construct invalid internal keys (e.g. “[object HTMLFormElement]...”), breaking patching and lookup logic in subtle ways.

This prevents DOM clobbering from influencing Zone’s internal symbol generation and keeps the patching system stable even in the presence of malicious or unexpected global values.

(cherry picked from commit e50f504b2f)
2026-05-29 14:54:21 +02:00
rootvector2 4795b35d5b fix(common): only strip a literal /index.html suffix from URLs
Hit this while exercising `Location.normalize` with route paths that end in non-`.html` suffixes.

The unescaped `.` in the strip regex inside `_stripIndexHtml` matches any character, so e.g. `/foo/indexXhtml` and `/foo/index_html` both collapse to `/foo` before the base-path strip and end up resolving to the wrong route.

Escape the dot so only the literal `/index.html` suffix is stripped.

(cherry picked from commit d109bf90d5)
2026-05-29 13:16:10 +02:00
Alan Agius 6e71049021 refactor(platform-server): clean up and simplify url resolution utility
Trims leading/trailing whitespaces in resolveUrl to normalize input.

(cherry picked from commit e14d34e9ee)
2026-05-29 13:14:15 +02:00
Alan Agius 94d520fb67 fix(compiler): prevent namespaced SVG <style> elements from being stripped
Updates the template preparser to exclude namespaced SVG style tags (':svg:style') from the style elements set.

Previously, ':svg:style' elements were incorrectly classified as PreparsedElementType.STYLE, which caused them to be completely stripped from the final template DOM tree during the Render3 template transform and pushed into standard component stylesheets. By limiting the style element parsing to standard 'style' tags, namespaced SVG style tags remain safely in the template AST as normal DOM elements, preserving local SVG styling.

Closes #68977

(cherry picked from commit ec138c3645)
2026-05-28 14:02:54 +02:00
Angular Robot d88b796518 build: update cross-repo angular dependencies
See associated pull request for more information.
2026-05-27 16:41:13 -07:00
Cameron Smick 394c998345 refactor(core): replace the type of the getDirectiveMetadata property of ExternalCoreGlobalUtils with the type of the getDirectiveMetadata property of FrameworkAgnosticGlobalUtils.
Modifying these types will allow Client-Only Wiz (and other frameworks) to implement ExternalCoreGlobalUtils & InternalCoreGlobalUtils instead of FrameworkAgnosticGlobalUtils, which includes additional properties they shouldn't implement.

(cherry picked from commit 06d3758929)
2026-05-27 16:37:34 -07:00
Cameron Smick 76a8c87725 refactor(core): Split the ng global into internal and external objects
Split the `ng` global interface into two interfaces:
* `ExternalCoreGlobalUtils` includes all the functionality which has been shipped in a long-lived Angular version externally and which is subject to the versioning constraints described above.
* `InternalCoreGlobalUtils` includes internal-only functionality which has **not** been shipped in a long-lived Angular version.

This split means that all APIs in `InternalCoreGlobalUtils` can be iterated and evolved at a much faster pace. Angular DevTools can support those features, and we can make breaking changes more-or-less whenever we want. The downside is that external Angular developers cannot take advantage of those APIs or else we would be subject to the same versioning constraint we're trying to avoid here.

This means we can use `InternalCoreGlobalUtils` as a kind of "beta" channel for new DevTools APIs. Once that functionality is validated and the design is stabilized, the feature can be moved into `ExternalCoreGlobalUtils` and made available for external Angular developers when we're ready to commit to the long-lived version constraint. This will hopefully help us strike a better balance between iterating on new APIs quickly and maintaining stable APIs for external Angular users.

(cherry picked from commit d069c55ab4)
2026-05-27 16:37:34 -07:00
Matthieu Riegler f7b3ed8db2 fix(http): Introduce a max buffer size for fetch requests on SSR
By default, the `FetchBackend` on SSR will limit the response body size to 10 MB.
If the response body exceeds this limit, an error will be thrown.

This default value can be configured by providing by setting the `maxResponseBodySize` in `provideServerRendering`.

This is to prevent DoS on the server when loading large files

(cherry picked from commit 2acca1165d)
2026-05-27 16:36:55 -07:00
Yenya030 618c850282 fix(http): exclude withCredentials requests from transfer cache
Update the transfer cache check to safely exclude all requests sent with the `withCredentials` flag.

By default, the HTTP transfer cache avoids caching user-specific responses to prevent sensitive data exposure or incorrect caching. While requests with explicit headers like `Cookie` or `Authorization` are excluded by default, requests can also be sent with credentials via the `withCredentials` flag without having those headers explicitly declared on the request object.

To keep user-specific responses from being cached, exclude `withCredentials` requests unconditionally, even when the `includeRequestsWithAuthHeaders` option is set to true.

(cherry picked from commit 34090cb12e)
2026-05-27 14:13:23 -07:00
Yenya030 86390f2be4 fix(http): skip TransferCache for cookie-bearing requests by default
Treat requests with a Cookie header like other auth-bearing requests and skip TransferCache caching them by default.

This preserves the explicit opt-in path via includeRequestsWithAuthHeaders, adds regression coverage for cookie-bearing requests, and updates the SSR guide to document the behavior.

(cherry picked from commit ab459798d9)
2026-05-27 14:13:23 -07:00
Matthieu Riegler e6cfaf5672 fix(http): prevent httpResource from leaking a subscription
Priori to this commit, in the case the subscription was emitting synchronous we were leaking the subscription. This commit fixes it.

(cherry picked from commit 6388675878)
2026-05-27 13:06:52 -07:00
Matthieu Riegler b20f0fe078 fix(core): prevent rxResource from leaking a subscription
Priori to this commit, in the case the subscription was emitting synchronous we were leaking the subscription. This commit fixes it.

(cherry picked from commit e0e902a8fa)
2026-05-27 13:06:52 -07:00
RonGamzu d9c38e552d docs: fix typos in source code comments
(cherry picked from commit 6f56202755)
2026-05-27 11:18:27 -07:00
cexbrayat eb600aa3b2 refactor(forms): mark date and limit signal forms APIs public
Promote the signal forms date validator and limit metadata APIs from experimental to public API.

(cherry picked from commit 842cf8f31b)
2026-05-27 11:16:25 -07:00
Kristiyan Kostadinov 61a48e99aa fix(core): do not register dom triggers when defer blocks are in manual mode
Fixes that we were registering DOM triggers even if the `@defer` block is set up to be rendered manually. This matches the behavior we already have for timer triggers.

Fixes #68800.

(cherry picked from commit abc61aaf7c)
2026-05-27 10:54:03 -07:00
Andrew Scott d9f9a0835c fix(zone.js): avoid type error on custom object rejection with rejection property
Ensure that when a custom object with a 'rejection' property is thrown as a raw promise rejection, the unhandled promise rejection error logger does not crash with a TypeError while trying to access undefined zone properties.

Also wrap microtask queue draining and task frame counter updates with defensive try-finally blocks to guarantee internal scheduler states are properly reset under any potential call stack exception unwinding scenarios.

(cherry picked from commit fa7580061b)
2026-05-27 10:45:20 -07:00
SkyZeroZx d0c4951a9b fix(service-worker): Preserves HTTP cache mode in asset group requests
Ensures explicit HTTP cache mode from incoming requests is forwarded and maintained when creating fetch requests for assets, aligning with expected fetch behavior and preventing unintended cache handling.

(cherry picked from commit 31399c2171)
2026-05-27 10:43:20 -07:00
SkyZeroZx a02797d045 fix(service-worker): Preserves explicit 'credentials: omit' in asset requests
Ensures that explicitly provided `credentials: 'omit'` options are preserved
when creating new requests, preventing unintended credential inclusion.

(cherry picked from commit 5b0e9663e5)
2026-05-27 10:43:20 -07:00