Skip to content

Reject alias-bomb YAML front matter before parsing#26

Merged
JeroenDeDauw merged 1 commit into
masterfrom
bound-front-matter-yaml-parsing
Jul 7, 2026
Merged

Reject alias-bomb YAML front matter before parsing#26
JeroenDeDauw merged 1 commit into
masterfrom
bound-front-matter-yaml-parsing

Conversation

@JeroenDeDauw

Copy link
Copy Markdown
Member

Authored with Claude Code (claude-opus-4-8 (max)), directed by Jeroen. Closes a denial-of-service vector in YAML front matter: Yaml::parse() resolves anchors and aliases, so a few hundred bytes of aliased YAML (a "billion laughs" bomb) expands exponentially — parsing stays cheap, but ParserOutput serializes the result into the parser cache, materializing the full expansion and exhausting memory uncatchably (reachable by any editor, since Markdown is the default content model everywhere). A FrontMatterGuard inspects only the raw block (never a parsed structure, so its cost stays bounded by input size) and rejects front matter that uses more than a handful of anchor/alias markers — including aliases pinned against a quoted key's colon in JSON-style flow mappings — or exceeds a generous size ceiling; the exact rejected block is stripped so nothing leaks into the body. Legitimate metadata (including &/* inside plain scalars and the occasional single-anchor reuse) still parses unchanged.

YAML front matter is parsed with Yaml::parse(), which resolves anchors and
aliases. A few hundred bytes of aliased YAML (a "billion laughs" bomb)
expands exponentially: parsing stays cheap, but ParserOutput serializes the
result into the parser cache, materializing the full expansion and
exhausting memory uncatchably -- reachable by any editor, since Markdown is
the default content model everywhere.

Add a FrontMatterGuard that inspects only the raw block (never a parsed
structure, so its cost stays bounded by the input size) and rejects front
matter that uses more than a handful of anchor/alias markers or exceeds a
generous size ceiling. Rejected front matter is treated as absent and
stripped from the body. Legitimate metadata -- including & and * inside
plain scalars and the occasional single-anchor reuse -- still parses
unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.76%. Comparing base (18af6b3) to head (c818c71).

Additional details and impacted files
@@             Coverage Diff              @@
##             master      #26      +/-   ##
============================================
+ Coverage     82.37%   82.76%   +0.39%     
- Complexity      314      323       +9     
============================================
  Files            33       34       +1     
  Lines           834      853      +19     
============================================
+ Hits            687      706      +19     
  Misses          147      147              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@JeroenDeDauw JeroenDeDauw marked this pull request as ready for review July 7, 2026 12:40
@JeroenDeDauw JeroenDeDauw merged commit 62ac2f3 into master Jul 7, 2026
12 checks passed
@JeroenDeDauw JeroenDeDauw deleted the bound-front-matter-yaml-parsing branch July 7, 2026 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants