Skip to content

fix: bound YAML anchor/alias expansion to prevent OOM (billion laughs) (#3000) - #3005

Merged
Vincent Biret (baywet) merged 1 commit into
support/v2from
fix/oom-to-v2
Aug 11, 2026
Merged

fix: bound YAML anchor/alias expansion to prevent OOM (billion laughs) (#3000)#3005
Vincent Biret (baywet) merged 1 commit into
support/v2from
fix/oom-to-v2

Conversation

@baywet

Copy link
Copy Markdown
Member

port of #3000 to v2

#3000)

* fix: bound YAML anchor/alias expansion to prevent OOM (billion laughs)

The YAML reader converts the SharpYaml node graph - a DAG in which aliases
share a single instance - into a System.Text.Json JsonNode tree, allocating
a fresh node per path. Because JsonNode is single-parent, shared aliases must
be duplicated, so a tiny document with nested anchors/aliases expands
exponentially and exhausts process memory (CWE-400, uncontrolled resource
consumption).

Add a conversion budget to YamlConverter.ToJsonNode that caps the total
materialized node count (5,000,000) and nesting depth (64, mirroring the
System.Text.Json default already enforced on the JSON reader path). On breach
it throws OpenApiReaderException, which OpenApiYamlReader.Read converts into an
OpenApiDiagnostic error instead of allowing an OOM. Public API is unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 022bbd4f-e5e7-447a-bcdf-b2a4efaf75c3

* feat: make YAML conversion limits configurable

Expose YamlConverter.MaxDepth and MaxNodeCount as public static properties
(defaulting to DefaultMaxDepth=64 and DefaultMaxNodeCount=5,000,000) so
consumers can raise the limits for legitimately large/deep documents or lower
them to fail faster on known-small inputs, without needing a library change.
Setters validate that the value is greater than zero. Public API entries added.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 022bbd4f-e5e7-447a-bcdf-b2a4efaf75c3

* uint instead

---------

Co-authored-by: Treicy Sanchez Gutierrez (from Dev Box) <treicys@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 022bbd4f-e5e7-447a-bcdf-b2a4efaf75c3
@github-code-quality

Copy link
Copy Markdown

Code Coverage Overview

Languages: C#

C# / code-coverage/dotnet

The overall coverage in commit 4db9af0 in the fix/oom-to-v2 branch is 42%. The coverage in commit dbf1f9e in the support/v2 branch is 89%.

Show a code coverage summary of the most impacted files.
File support/v2 dbf1f9e fix/oom-to-v2 4db9af0 +/-
/home/runner/wo...MapParameter.cs 100% 0% -100%
/home/runner/wo...Deserializer.cs 81% 0% -81%
/home/runner/wo...pyReferences.cs 63% 31% -32%
/home/runner/wo...piJsonReader.cs 100% 72% -28%
/home/runner/wo...Deserializer.cs 90% 62% -28%
/home/runner/wo...s/OpenApiTag.cs 100% 76% -24%
/home/runner/wo...Deserializer.cs 96% 81% -15%
/home/runner/wo...Deserializer.cs 97% 89% -8%
/home/runner/wo...piComponents.cs 94% 87% -7%
/home/runner/wo...Deserializer.cs 92% 88% -4%

@sonarqubecloud

Copy link
Copy Markdown

@baywet
Vincent Biret (baywet) merged commit a361360 into support/v2 Aug 11, 2026
17 checks passed
@baywet
Vincent Biret (baywet) deleted the fix/oom-to-v2 branch August 11, 2026 20:21
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.

3 participants