Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

Angular SSR heap OOM during mXSS stabilization, amplified by transient Domino ID indexing

Ouverte
#70,873 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Évaluation

Difficulté
5/5
Temps estimé
Plus d'une semaine
Accessibilité débutants
35/100
Type d'issue
Bug
Clarté
À clarifier
Activité
Active
Stack technique
angular, node.js, typescript
Domaine
backend, performance

Piste de recherche

Start in core / platform-server and the bundled Domino integration, then reproduce the linked proof of concept while comparing repeated id attributes with the xx control. Done means the reported SSR cases no longer exhaust the Node.js heap, with coverage for the mXSS stabilization and temporary-document behavior described here.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

area: server gemini-triaged
Which @angular/* package(s) are the source of the bug?

core / platform-server (bundled Domino)

Is this a regression?

No

Description

Angular SSR can exhaust the Node.js heap when HTML rendered through a normal [innerHTML] binding contains a specific combination of active-formatting elements and repeated id attributes.

Example:

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  template: `<div [innerHTML]="content"></div>`,
})
export class App {
  readonly content = attackerControlledHtml;
}

On the server, Angular parses the value into an inert Domino document as part of HTML sanitization. For the minimized input, the sanitizer stabilization path performs multiple fragment parses.

During each parse, Domino maintains Document.byId / MultiId even though the document is only a temporary document used to build a fragment.
With the minimized candidate, the parser creates a large reconstructed DOM and adds more than 100k transient ID-index memberships before those nodes are moved out of the temporary document.

An equal-byte control changes only the attribute name from id to xx.

candidate: repeated id attributes
control:   repeated xx attributes

Both inputs have the same size and produce the same element/attribute topology and serialization size, but only the id version enters Domino's ID index.

In the original 256 MiB validation, the 3,988-byte id candidate terminated all five workers:

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

I also tested larger heap limits with payloads calibrated for each limit:

V8 old space Request body xx control id candidate
256 MiB 3,988 B 5/5 healthy (original run; 4/5 on repeat) 5/5 fatal V8 OOM
512 MiB 6,493 B 3/3 HTTP 200 + healthy worker 3/3 fatal V8 OOM
1,024 MiB 11,431 B 3/3 HTTP 200 + healthy worker 3/3 fatal V8 OOM

More context : https://issuetracker.google.com/u/1/issues/563071374

Follow-up: two contributing memory costs

Further testing shows that Domino's temporary ID index is an amplifier, but not the only reason this reaches the heap limit.

Active-formatting reconstruction already creates a large DOM from the short input. During Angular's mXSS stabilization loop, the previous inert template also remains alive while the next fragment is parsed.

Build Request body xx OOM id OOM
Original, repeat 3,988 B 1/5 5/5
Lazy Domino ID index only 3,988 B 0/10 1/10
Early mXSS template cleanup only 3,988 B 0/5 0/5

The lazy ID-index change greatly reduces the id failures, while clearing the previous inert template removes the OOM at this size in my tests.

Larger inputs can still exhaust the heap, including inputs without id. I haven't rerun the 512 MiB and 1,024 MiB cases with these changes.

See: https://github.com/SkyZeroZx/angular-ssr-mxss-domino-oom-poc

Langage dominant
TypeScript
Étoiles
101k
Forks
28.1k
Merge moyen
2 j 6 h
PR mergées (30 j)
307

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de angular/angular

Toutes les issues de angular/angular

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.