← Back to News
Security

Symfony Hardens Its YAML Parser Against a "Billion Laughs" DoS

Symfony Hardens Its YAML Parser Against a "Billion Laughs" DoS

Three YAML Parser DoS Bugs, One Release

On 20 May 2026 Symfony disclosed three denial-of-service vulnerabilities in its YAML component and shipped fixes in 5.4.52, 6.4.40, 7.4.12, and 8.0.12. The headline issue, CVE-2026-45304, is a classic "Billion Laughs" memory-amplification attack; two siblings — CVE-2026-45133 (stack exhaustion) and CVE-2026-45305 (regex backtracking) — round out a hardening pass on parsing untrusted YAML. All affect every supported branch before the fixed releases.

Billion Laughs via Recursive Aliases

Symfony\Component\Yaml\Parser resolves YAML aliases (*anchor) as it parses. When an alias points at a collection — an array, stdClass, or TaggedValue-wrapped collection — that itself contains aliases pointing at other collections, resolution expands exponentially. A few kilobytes of YAML can balloon into a multi-gigabyte in-memory structure and exhaust the worker's RAM. It is the YAML analogue of the XML "Billion Laughs" entity-expansion attack, and it fires on any endpoint that parses attacker-controlled YAML.

This is a hazard JSON simply doesn't have: JSON has no anchors, aliases, or references, so a JSON document's in-memory size is bounded by its byte size. The reference machinery that makes YAML convenient for humans is exactly what makes it dangerous to parse untrusted.

Stack Exhaustion and Catastrophic Backtracking

The two siblings target the same "untrusted YAML" surface:

  • CVE-2026-45133 — deeply nested mappings or sequences drive both the block-level and inline parsers into unbounded recursion, exhausting the PHP call stack and crashing the worker.
  • CVE-2026-45305 — a single oversized %YAML directive header (or comment / document-marker line) triggers catastrophic backtracking in the parser's cleanup() regex, hanging the request (a ReDoS).

The Fix — Alias Limits and Depth Guards

The patched parser counts collection-alias resolutions in a shared ParserState, capped by a configurable $maxAliasesForCollections limit (default 128, following SnakeYAML's model); scalar aliases stay unrestricted because they can't drive exponential growth. For fully untrusted input, a new Yaml::PARSE_EXCEPTION_ON_ALIAS flag rejects aliases outright. The recursion and regex bugs gained explicit depth and length guards. The Billion Laughs issue was reported by Pietro Tirenna (Shielder) and fixed by Nicolas Grekas.

The practical takeaway is the same one that motivates running JSON tools locally: never parse untrusted serialized data with an unbounded parser. If you only need data interchange — not anchors and shared references — converting YAML to plain JSON first removes the entire class of alias-expansion attacks before the payload reaches your application.

Sources

Related on fixjson.org