The `parseUrl` function in `ServerPlatformLocation` uses `new URL(urlStr, origin)` to parse incoming request URLs during SSR. Per the WHATWG URL specification, protocol-relative URLs (`//evil.com`) and backslash-prefixed URLs (`/\evil.com`) can override the hostname component of the base URL.
This vulnerability typically manifests in SSR setups (e.g., Express) where `req.url` is passed directly to `renderApplication` or `renderModule`:
```typescript
// Example usage in an Express server handling: http://localhost:4000//evil.com
app.get('*', async (req, res) => {
const html = await renderApplication(bootstrap, {
document: template,
url: req.url, // req.url is "//evil.com"
});
res.send(html);
});
```
Fixes that we weren't sanitizing attribute bindings with interpolations if they're marked for translation, for example: `<a href="{{evilLink}}" i18n-href></a>`.
Also adds a bit more test coverage for our sanitization.
Translators are not allowed to write HTML which creates URI attributes. I opted to ban any values going into an attribute at all, to prevent even links to malicious content, rather than just sanitizing URIs.
I also converted this blocklist into an allowlist. Now, we only allowing setting known attributes (while sanitizing URI attributes). This significantly reduces risk of missing a vulnerable attribute and does not require an exhaustive list of all potential attributes.
BREAKING CHANGE: Angular now only applies known attributes from HTML in translated ICU content. Unknown attributes are dropped and not rendered.
(cherry picked from commit 03da204b6d)
This commit updates the DOM security schema and sanitization logic to properly recognize and sanitize `href` and `xlink:href` attributes on SVG `<script>` elements.
This commit implements a security fix to prevent XSS vulnerabilities where SVG animation elements (`<animate>`, `<set>`, etc.) could be used to modify the `href` or `xlink:href` attributes of other elements to `javascript:` URLs.
The fix introduces a runtime validation step:
- A new [ɵɵValidateAttribute](cci:1://file:///usr/local/google/home/alanagius/git/angular/packages/core/src/sanitization/sanitization.ts:276:0-288:1) instruction is used when `attributeName` is bound on SVG animation elements.
- If executed, a `RuntimeError` is thrown, preventing the binding.
- The compiler now identifies `attributeName` on SVG animation elements as security-sensitive and injects this validation.
Additionally, the DOM security schema has been updated to include a comprehensive list of MathML and SVG elements that accept `href` or `xlink:href` attributes, ensuring they are correctly treated as `SecurityContext.URL` and sanitized. This prevents malicious URLs from being bound to these attributes.
http://b/463880509
The XSRF interceptor previously failed to detect protocol-relative URLs (starting with `//`) as absolute URLs. This allowed requests to such URLs to include the XSRF token, potentially leaking it to external domains.
This change updates the interceptor to correctly identify protocol-relative URLs as absolute and exclude them from receiving the XSRF token.
* fix(core): introduce `BootstrapContext` for improved server bootstrapping
This commit introduces a number of changes to the server bootstrapping process to make it more robust and less error-prone, especially for concurrent requests.
Previously, the server rendering process relied on a module-level global platform injector. This could lead to issues in server-side rendering environments where multiple requests are processed concurrently, as they could inadvertently share or overwrite the global injector state.
The new approach introduces a `BootstrapContext` that is passed to the `bootstrapApplication` function. This context provides a platform reference that is scoped to the individual request, ensuring that each server-side render has an isolated platform injector. This prevents state leakage between concurrent requests and makes the overall process more reliable.
BREAKING CHANGE:
The server-side bootstrapping process has been changed to eliminate the reliance on a global platform injector.
Before:
```ts
const bootstrap = () => bootstrapApplication(AppComponent, config);
```
After:
```ts
const bootstrap = (context: BootstrapContext) =>
bootstrapApplication(AppComponent, config, context);
```
A schematic is provided to automatically update `main.server.ts` files to pass the `BootstrapContext` to the `bootstrapApplication` call.
In addition, `getPlatform()` and `destroyPlatform()` will now return `null` and be a no-op respectively when running in a server environment.
The hardcoded config was introduced because suppressing the diagnostic
via `extendedDiagnostics` in the TS config was unreliable in google3.
This has since been fixed and the workaround is no longer needed.
PR Close#61622
Prevents esbuild generated metadata files from being included in build artifacts. This reduces package size and avoids shipping unnecessary internal build data.
PR Close#61636
Since the duplication root-cause was solved by the previous commit, we
can revert/drop the logic that was added back then to overcome this
problem with Tsurge.
PR Close#61421
PR Close#61612
Currently there can be cases, exlusively in 3P, where multiple tsconfig
projects have overlap of source files. This is the default setup of new
CLI applications as well.
When this is the case, Tsurge will treat each tsconfig as an isolated
compilation unit (given the concepts and mental model to support
scalable batching). This is wrong though, and the same `.ts` source file
can appear in two migration invocations; resulting in duplicate
replacements or analysis (depending on the migration).
We've worked around this problem in the past by deduplicating
replacements, or migrating to an ID-based approach with natural
deduplication. This worked, but it's just working around the root cause.
This commit attempts to fix the root cause by adjusting Tsurge to ensure
that no source file ever appears in two compilation units. This is
naively achieved by not adding a source file to a migration unit, if it
was part of a previous one. This is expected to be fine given the nature
of Tsurge migrations that are built to operate on isolated pieces
anyway— so it shouldn't be problematic if e.g. `app.component.ts` ends
up being part of the test tsconfig compilation unit (we avoid this order
though by visiting build targets first).
PR Close#61421
PR Close#61612
In this commit, we check whether the application is destroyed before calling `serviceWorker.register(...)`. We should not register the worker because other resources will not be available.
PR Close#61101
Avoids duplication of the `FactoryTarget` enums. This is necessary
now because we are exposing the previously deeply-imported JIT facade
now via the exports; and the typing integration tests surface a type
conflict due to the different duplicated enums.
PR Close#61571
These helpers are often imported by various tests throughout the
repository, but the helpers aren't exported/exposed from the public
entry-point; even though they confusingly reside in there.
This commit fixes this, and moves the helpers into
`packages/private/testing`. This is a preparation for the `ts_project`
migration where we don't want to leverage deep imports between packages.
PR Close#61571
The observable terminates immediately when `error` is called, and no further emissions or completion notifications occur. Thus, we have to remove the `abort` listener in both the `error` and `complete` notifications.
PR Close#58306
Streams left in a pending state (due to `break` without cancel) may continue consuming or holding onto data behind the scenes. Calling `reader.cancel()` allows the browser or the underlying system to release any network or memory resources associated with the stream.
PR Close#61528
Currently we construct the HMR replacement URL inline by calling into the native `URL` constructor. This can cause conflicts with user code that defines a symbol called `URL`.
These changes resolve the issue by moving the URL construction into a separate function. This has a secondary benefit of making the generated code easier to follow and allowing us to update the URL without changing the compiled code.
Fixes#61517.
PR Close#61550
This change ensures that prior results for all files are retained even when
a request is made such that we only need a shim for a single file. Prior
to this change, any prior results that were not part of the request were discarded.
PR Close#61487
Use an unstamped version of the compiler when it runs in `ng_project` as it will get stamped appropriately
whenever the generated code gets stamped after its usage."
PR Close#61479
Adds `__PURE__` annotations to non-default `new` expressions to enable tree-shaking, even if they are not referenced. These variables are not dropped when Angular is imported from a module that has `sideEffects` set to `true`.
PR Close#61452