Repository navigation
Reject a literal 0x1A after the value in strict mode (CVE-2026-113602) - #305
Open
knutwannheden wants to merge 1 commit into
Open
knutwannheden wants to merge 1 commit into
knutwannheden wants to merge 1 commit into
Conversation
The parser marks the end of input with the character 0x1A, so a literal
0x1A in the input looked like the end of the document. The trailing-data
check of MODE_RFC4627 and MODE_STRICTEST (JSONValue.parseStrict and
isValidJsonStrict) therefore accepted {"a":1} followed by 0x1A and
arbitrary garbage as {"a":1}, on the String, byte[], Reader and
InputStream backends.
The trailing-data check now asks the backend whether the input is
exhausted. The String and byte[] parsers compare the position with the
length, and the Reader parser (which also serves InputStream) records
whether its last read returned -1. Modes that accept trailing data keep
treating a literal 0x1A as the end of input.
Fixes netplex#302 (CVE-2026-113602).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
JSONValue.isValidJsonStrictreturnstruefor{"a":1}followed by a 0x1A byte and arbitrary trailing data, andparseStrictreturns{"a":1}while silently dropping the rest (#302, CVE-2026-113602). A strict validator in front of another JSON parser therefore passes documents that the other parser reads differently. Every backend is affected: String, byte[], Reader and InputStream.The parser marks the end of input by setting the current character to
EOI = 0x1A. The trailing-data checkc != EOIthatMODE_RFC4627andMODE_STRICTESTrun after the value cannot tell that marker apart from a 0x1A read from the input. Before this change, both modes returned these results on all four backends:Ask the backend whether the input ended
The trailing-data check now calls a new
isEndOfInput()instead of comparingcwith the marker:JSONParserMemory(String, byte[]) returnspos >= len.JSONParserReader(Reader, InputStream) returns a flag that each read sets from whetherin.read()returned -1.The other
c == EOIchecks are left alone. The parser never reads past the marker, so a 0x1A that an inner check took for the end is still the current character when the trailing-data check runs. In strict mode those inner checks already reject it, as an unexpected EOF or, inside a string, as a control character.Consulting the flag at every check was rejected because it would turn a literal 0x1A into an ordinary control character.
skipSpaceskips every character up to' ', so{"a":1}<0x1A>would then pass strict mode as trailing whitespace, and permissive results would change ([1<0x1A>,2]would parse as[1,2]).Not changed here
Modes that accept trailing data (
MODE_PERMISSIVE,MODE_JSON_SIMPLE, andMultipleJsonParser.hasNext()) still treat a literal 0x1A as the end of input. They already return the first value and ignore whatever follows it, so the 0x1A gets nothing past a check. Custom modes that omitACCEPT_TAILLING_DATAorACCEPT_TAILLING_SPACErun the trailing-data check and now reject it too.Tests
TestCVE2026113602parses withMODE_RFC4627on all four backends.strictParserRejectsSubAfterValuefails on every backend without the fix.strictParserRejectsSubInStringpasses either way. It keeps a 0x1A inside a string rejected, and fails on Reader and InputStream whenreadString2is mutated to append the 0x1A as data.Fixes #302.