CVE-2026-101895

Updated on 14 Oct 2026

Severity

8.7 High severity

Details

CVSS score
8.7
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Overview

About vulnerability

A Denial of Service (DoS) vulnerability exists in @angular/platform-server’s DOM emulation parser (domino). When processing untrusted user input containing an incomplete DOCTYPE declaration ending with whitespace before EOF (such as <!DOCTYPE html ), the HTML parser enters an infinite synchronous loop, pegging CPU utilization at 100% and completely freezing the Node.js server process.

Technical Description

In Angular Server-Side Rendering (SSR), @angular/platform-server uses domino to parse and sanitize HTML bound through template bindings (such as [innerHTML]) or manipulated via DOM APIs.

In Domino’s HTML parser (lib/HTMLParser.js), tokenizer states that specify fixed lookahead—such as after_doctype_name_state (lookahead = 6)—rely on the state handler function to explicitly advance the character index pointer (nextchar). While branches for whitespace, >, and keyword matching advance nextchar, the EOF branch (case -1: // EOF) emitted doctype and EOF tokens without advancing nextchar or transitioning out of the state:

case -1: // EOF
forcequirks();
emitDoctype();
emitEOF();
break;

Because nextchar remained unchanged pointing to the EOF marker character (\uFFFF), the scanner loop (while (nextchar < numchars)) repeatedly re-invoked after_doctype_name_state with codepoint = EOF indefinitely. In Node.js’s single-threaded runtime, this synchronous loop starves the event loop entirely.

Impact & Reachability

  • Reachability: The vulnerability is reachable in any Angular SSR application where untrusted user input is bound to [innerHTML], interpolated into markup, or sanitized on the server.
  • Impact: Successful exploitation allows an unauthenticated remote attacker to cause an immediate Denial of Service (DoS) by sending a payload containing an incomplete DOCTYPE (e.g., <!DOCTYPE html ). The Node.js SSR process locks up at 100% CPU and ceases responding to all concurrent and subsequent HTTP requests.

Proof of Concept:

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

@Component({
selector: 'app-root',
standalone: true,
template: `<div [innerHTML]="payload"></div>`,
})
export class AppComponent {
// Attacker-controlled input containing an incomplete DOCTYPE ending with whitespace
payload = '<!DOCTYPE html ';
}

Workarounds

  • Avoid binding untrusted user input directly to [innerHTML] in server-rendered templates; use standard text interpolation ({{ userInput }}) or [textContent] when raw HTML rendering is not required.
  • Validate or sanitize user input before passing it to [innerHTML] on the server by stripping or rejecting strings matching /^<!DOCTYPE/i.

Details

Affected product:
AngularJS , analogjs-astro-angular , analogjs-vite-plugin-angular , angular-animations , angular-build , angular-common , angular-compiler , angular-compiler-cli , angular-core , angular-create , angular-devkit-build-angular , angular-devkit-core , angular-devkit-schematics-cli , angular-elements , angular-estree-parser , angular-forms , angular-language-server , angular-localize , angular-platform-browser , angular-platform-browser-dynamic , angular-platform-server , angular-pwa , angular-router , angular-service-worker , angular-ssr , angular-upgrade , create-storybook , domino , ng-packagr , ngtools-webpack , nguniversal , nguniversal-common , sb , schematics-angular , sentry-angular , sentry-astro , sentry-deno , sentry-ember , sentry-gatsby , sentry-javascript , sentry-replay , sentry-wasm , storybook , storybook-addon-a11y , storybook-addon-actions , storybook-addon-backgrounds , storybook-addon-controls , storybook-addon-docs , storybook-addon-essentials , storybook-addon-highlight , storybook-addon-interactions , storybook-addon-jest , storybook-addon-links , storybook-addon-mdx-gfm , storybook-addon-measure , storybook-addon-onboarding , storybook-addon-outline , storybook-addon-storysource , storybook-addon-themes , storybook-addon-toolbars , storybook-addon-viewport , storybook-angular , storybook-blocks , storybook-builder-manager , storybook-builder-vite , storybook-builder-webpack5 , storybook-channels , storybook-cli , storybook-client-logger , storybook-codemod , storybook-components , storybook-core , storybook-core-common , storybook-core-events , storybook-core-server , storybook-core-webpack , storybook-csf-plugin , storybook-csf-tools , storybook-docs-tools , storybook-ember , storybook-experimental-addon-test , storybook-experimental-nextjs-vite , storybook-html , storybook-html-vite , storybook-html-webpack5 , storybook-instrumenter , storybook-manager , storybook-manager-api , storybook-nextjs , storybook-node-logger , storybook-preact , storybook-preact-vite , storybook-preact-webpack5 , storybook-preset-create-react-app , storybook-preset-html-webpack , storybook-preset-preact-webpack , storybook-preset-react-webpack , storybook-preset-server-webpack , storybook-preset-svelte-webpack , storybook-preset-vue3-webpack , storybook-preview , storybook-preview-api , storybook-react , storybook-react-dom-shim , storybook-react-native-web-vite , storybook-react-vite , storybook-react-webpack5 , storybook-router , storybook-server , storybook-server-webpack5 , storybook-source-loader , storybook-svelte , storybook-svelte-vite , storybook-svelte-webpack5 , storybook-sveltekit , storybook-telemetry , storybook-test , storybook-theming , storybook-types , storybook-vue3 , storybook-vue3-vite , storybook-vue3-webpack5 , storybook-web-components , storybook-web-components-vite , storybook-web-components-webpack5
Affected packages:
@angular/animations @ 17.3.12 (+3123 more)

Fixes