Skip to content

Unbounded recursion in DefaultUrlSerializer.parse() can cause router-level DoS with crafted URLs #66757

@rmtsixq

Description

@rmtsixq

Which @angular/* package(s) are the source of the bug?

router

Is this a regression?

No

Description

The Angular Router's DefaultUrlSerializer.parse() contains unbounded mutual recursion between
parseChildren() and parseParens() when handling deeply nested or malformed URLs containing
parentheses.

This can lead to excessive CPU usage, event-loop blocking, or stack overflow depending on runtime
limits. The issue is not exception-based and may not always throw an error, which makes it harder
to detect in production environments.

This is a parser-level denial of service condition caused by uncontrolled recursion. There is no
depth limit, recursion guard, or complexity check in the URL parsing logic.

Relevant code paths:

  • parseChildren()parseParens()
  • parseParens()parseChildren()

Because this logic is part of a core framework component, it is expected to be safe-by-default.
Relying on every application developer to defensively wrap router parsing logic in try/catch
does not mitigate CPU exhaustion or event-loop blocking.

This affects server-side rendering and custom Node/Express integrations where DefaultUrlSerializer
is used directly or indirectly.

Please provide a link to a minimal reproduction of the bug

No public repo required. The issue can be reproduced by calling: const serializer = new DefaultUrlSerializer(); serializer.parse(url); Where url contains deeply nested parentheses, for example: "/((((((((((((((((((((((a))))))))))))))))))))))" Observed behavior: high CPU usage / hang / stack overflow depending on environment.

Please provide the exception or error you saw

In many cases no exception is thrown.
Observed effects include:
- Event loop blocking
- High CPU usage
- Stack overflow in some environments

This is not an exception-based failure.

Please provide the environment you discovered this bug in (run ng version)


Anything else?

This is a classic uncontrolled recursion / resource exhaustion issue (CWE-674 / CWE-400).

Even if higher-level frameworks catch errors, the lack of a recursion or depth guard in the router
parser itself means a single crafted request can degrade availability.

Suggested mitigation:

  • Introduce a maximum recursion depth
  • Add a parsing complexity guard
  • Fail fast on excessive nesting

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions