High severity7.5OSV Advisory· Published Oct 9, 2025· Updated Apr 15, 2026
CVE-2025-11573
CVE-2025-11573
Description
An infinite loop issue in Amazon.IonDotnet library versions <v1.3.2 may allow a threat actor to cause a denial of service through a specially crafted text input.
To mitigate this issue, users should upgrade to version v1.3.2. As of August 20, 2025, this library has been deprecated and will not receive further updates.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
Amazon.IonDotnetNuGet | < 1.3.2 | 1.3.2 |
Affected products
1- Range: v0.9.0, v0.9.0-beta, v1.0.0, …
Patches
2d116f5574375edaff75fe5abFixes infinite loop bugs in text parsing of lobs and strings.
2 files changed · +219 −12
Amazon.IonDotnet/Internals/Text/TextScanner.cs+48 −12 modified@@ -202,7 +202,7 @@ public void LoadBlob(StringBuilder sb) var c = this.SkipOverWhiteSpace(CommentStrategy.Break); while (true) { - if (c == TextConstants.TokenEof) + if (c == CharacterSequence.CharSeqEof) { throw new UnexpectedEofException(); } @@ -217,7 +217,7 @@ public void LoadBlob(StringBuilder sb) } c = this.ReadChar(); - if (c == TextConstants.TokenEof) + if (c == CharacterSequence.CharSeqEof) { throw new UnexpectedEofException(); } @@ -1006,7 +1006,7 @@ private void SkipOverBlob() var c = this.SkipOverWhiteSpace(CommentStrategy.Break); while (true) { - if (c == TextConstants.TokenEof) + if (c == CharacterSequence.CharSeqEof) { throw new UnexpectedEofException(); } @@ -1020,7 +1020,8 @@ private void SkipOverBlob() } c = this.ReadChar(); - if (c == TextConstants.TokenEof) + + if (c == CharacterSequence.CharSeqEof) { throw new UnexpectedEofException(); } @@ -1038,21 +1039,40 @@ private void SkipTripleQuotedString(CommentStrategy commentStrategy) var c = this.ReadChar(); switch (c) { - case -1: + case CharacterSequence.CharSeqEof: throw new UnexpectedEofException(); case '\\': - this.ReadChar(); + var escaped = this.ReadChar(); + if (escaped == CharacterSequence.CharSeqEof) + { + throw new UnexpectedEofException(); + } + break; case '\'': c = this.ReadChar(); + if (c == CharacterSequence.CharSeqEof) + { + throw new UnexpectedEofException(); + } // the 2nd ' if (c == '\'') { c = this.ReadChar(); + if (c == CharacterSequence.CharSeqEof) + { + throw new UnexpectedEofException(); + } // the 3rd - if (c == this.ReadChar()) + var next = this.ReadChar(); + if (next == CharacterSequence.CharSeqEof) + { + throw new UnexpectedEofException(); + } + + if (c == next) { c = this.SkipOverWhiteSpace(commentStrategy); if (c == '\'' && this.Is2SingleQuotes()) @@ -1515,12 +1535,23 @@ private int SkipSingleQuotedString() var c = this.ReadStringChar(Characters.ProhibitionContext.None); switch (c) { - case -1: + case CharacterSequence.CharSeqEof: throw new UnexpectedEofException(); case '\'': - return this.ReadChar(); + var next = this.ReadChar(); + if (next == CharacterSequence.CharSeqEof) + { + throw new UnexpectedEofException(); + } + + return next; case '\\': - this.ReadChar(); + var escaped = this.ReadChar(); + if (escaped == CharacterSequence.CharSeqEof) + { + throw new UnexpectedEofException(); + } + break; } } @@ -1537,7 +1568,7 @@ private void SkipDoubleQuotedString() var c = this.ReadStringChar(Characters.ProhibitionContext.None); switch (c) { - case -1: + case CharacterSequence.CharSeqEof: throw new UnexpectedEofException(); case CharacterSequence.CharSeqEscapedNewlineSequence1: case CharacterSequence.CharSeqEscapedNewlineSequence2: @@ -1547,7 +1578,12 @@ private void SkipDoubleQuotedString() case '"': return; case '\\': - this.ReadChar(); + var escaped = this.ReadChar(); + if (escaped == CharacterSequence.CharSeqEof) + { + throw new UnexpectedEofException(); + } + break; } }
Amazon.IonDotnet.Tests/Internals/TextScannerTest.cs+171 −0 added@@ -0,0 +1,171 @@ +using System; +using System.IO; +using System.Text; +using Amazon.IonDotnet.Internals.Text; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Amazon.IonDotnet.Tests.Internals +{ + [TestClass] + public class TextScannerTest + { + private TextScanner CreateScanner(string input) + { + var bytes = System.Text.Encoding.UTF8.GetBytes(input); + var stream = new MemoryStream(bytes); + var textStream = new UnicodeStream(stream); + return new TextScanner(textStream); + } + + [TestMethod] + public void TestMalformedBlobHandling() + { + // Test simple malformed blob + var scanner = CreateScanner("{{"); + Assert.ThrowsException<UnexpectedEofException>(() => + { + scanner.NextToken(); + while (scanner.Token != TextConstants.TokenEof) + { + scanner.NextToken(); + } + }); + + // Test the specific malformed input that caused the infinite loop + var hexString = "282f5959595959595959593a3a282b2727357b7b7b7b7b7b7b7b27272728fb2b272829"; + var bytes = new byte[hexString.Length / 2]; + for (int i = 0; i < bytes.Length; i++) + { + bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); + } + + var stream = new MemoryStream(bytes); + var textStream = new UnicodeStream(stream); + scanner = new TextScanner(textStream); + + Assert.ThrowsException<UnexpectedEofException>(() => + { + scanner.NextToken(); + while (scanner.Token != TextConstants.TokenEof) + { + scanner.NextToken(); + } + }); + } + + [TestMethod] + public void TestSingleQuotedStringEofHandling() + { + // Test EOF in single-quoted string + var scanner = CreateScanner("'unterminated"); + Assert.ThrowsException<UnexpectedEofException>(() => + { + scanner.NextToken(); + while (scanner.Token != TextConstants.TokenEof) + { + scanner.NextToken(); + } + }); + + // Test EOF after escape in single-quoted string + scanner = CreateScanner("'escaped\\"); + Assert.ThrowsException<UnexpectedEofException>(() => + { + scanner.NextToken(); + while (scanner.Token != TextConstants.TokenEof) + { + scanner.NextToken(); + } + }); + } + + [TestMethod] + public void TestTripleQuotedStringEofHandling() + { + // Test EOF in triple-quoted string + var scanner = CreateScanner("'''unterminated"); + Assert.ThrowsException<UnexpectedEofException>(() => + { + scanner.NextToken(); + while (scanner.Token != TextConstants.TokenEof) + { + scanner.NextToken(); + } + }); + + // Test EOF after partial triple quote + scanner = CreateScanner("'''content''"); + Assert.ThrowsException<UnexpectedEofException>(() => + { + scanner.NextToken(); + while (scanner.Token != TextConstants.TokenEof) + { + scanner.NextToken(); + } + }); + + // Test EOF after escape in triple-quoted string + scanner = CreateScanner("'''escaped\\"); + Assert.ThrowsException<UnexpectedEofException>(() => + { + scanner.NextToken(); + while (scanner.Token != TextConstants.TokenEof) + { + scanner.NextToken(); + } + }); + } + + [TestMethod] + public void TestDoubleQuotedStringEofHandling() + { + // Test EOF in double-quoted string + var scanner = CreateScanner("\"unterminated"); + Assert.ThrowsException<UnexpectedEofException>(() => + { + scanner.NextToken(); + while (scanner.Token != TextConstants.TokenEof) + { + scanner.NextToken(); + } + }); + + // Test EOF after escape in double-quoted string + scanner = CreateScanner("\"escaped\\"); + Assert.ThrowsException<UnexpectedEofException>(() => + { + scanner.NextToken(); + while (scanner.Token != TextConstants.TokenEof) + { + scanner.NextToken(); + } + }); + } + + [TestMethod] + public void TestMalformedClobHandling() + { + // Test malformed clob with missing closing braces + var scanner = CreateScanner("{{\"clob content\""); + Assert.ThrowsException<UnexpectedEofException>(() => + { + scanner.NextToken(); + while (scanner.Token != TextConstants.TokenEof) + { + scanner.NextToken(); + } + }); + + // Test malformed clob with triple quotes + scanner = CreateScanner("{{{'''clob content"); + Assert.ThrowsException<UnexpectedEofException>(() => + { + scanner.NextToken(); + while (scanner.Token != TextConstants.TokenEof) + { + scanner.NextToken(); + } + }); + } + } +}
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-q5r6-9qwq-g2wjghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-11573ghsaADVISORY
- aws.amazon.com/security/security-bulletins/AWS-2025-022ghsaWEB
- github.com/amazon-ion/ion-dotnet/commit/edaff75fe5abbb71e647bed812c608c0c5e2fbabghsaWEB
- github.com/amazon-ion/ion-dotnet/pull/160ghsaWEB
- github.com/amazon-ion/ion-dotnet/releases/tag/v1.3.2nvdWEB
- github.com/amazon-ion/ion-dotnet/security/advisories/GHSA-q5r6-9qwq-g2wjnvdWEB
- aws.amazon.com/security/security-bulletins/AWS-2025-022/nvd
News mentions
0No linked articles in our index yet.