Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Confusion between \0 and EOF can lead to OutOfMemoryError #758

Closed
eamonnmcmanus opened this issue Aug 1, 2023 · 6 comments · Fixed by #759
Closed

Confusion between \0 and EOF can lead to OutOfMemoryError #758

eamonnmcmanus opened this issue Aug 1, 2023 · 6 comments · Fixed by #759

Comments

@eamonnmcmanus
Copy link
Contributor

JSONTokener.next() uses a 0 return to indicate EOF. But 0 is also returned when an actual \0 character is read. In some circumstances that can be used to circumvent parser checks. Parsing untrusted input could then potentially lead to OutOfMemoryError even for quite small input strings.

@johnjaylward
Copy link
Contributor

Do you have an actual test to validate this?

I'd argue that valid text input should never have a \0 in it in the first place, so treating it the same as EOF would just make the parsed JSON document invalid. From what I remember of the parser, this should make the parsing stop and if the JSON value is not complete, than the parse would fail with an JSONException

@eamonnmcmanus
Copy link
Contributor Author

Yes, I have a test that can provoke OutOfMemoryError with a small input, though I'm not going to publish it until a fix has been released. Yes, \0 should mean EOF everywhere, but it currently doesn't.

@johnjaylward
Copy link
Contributor

Without a PoC, I doubt anyone else will fix this.

Feel free to submit a PR.

I don't think I'd consider a OOME a security issue, but if you feel different, follow the instructions for those here:
https://github.com/stleary/JSON-java/wiki/FAQ#how-are-vulnerabilities-and-exploits-handled

@eamonnmcmanus
Copy link
Contributor Author

I think Denial of Service attacks kind of are security issues, aren't they? If you can make a server fall over by firing carefully-crafted JSON at it, that seems not great. Anyway, yes, my next step was to submit a PR.

(I have already shared repro details with @stleary.)

eamonnmcmanus added a commit to eamonnmcmanus/JSON-java that referenced this issue Aug 1, 2023
A better solution might be to use -1 instead 0 to represent EOF everywhere,
which of course means changing `char` variables to `int`. The solution here is
enough to solve the immediate problem, though.

Fixes stleary#758.
@stleary
Copy link
Owner

stleary commented Aug 1, 2023

@eamonnmcmanus Good catch and thanks for bringing this up. In this case, it's OK to post the recreate code and proposed fix.

@johnjaylward
Copy link
Contributor

DoS issues are about reliability. They are not security issues in and of themselves.

If the DoS leads to some other other issues like memory corruption or getting access to information that shouldn't be available, then it would track as security.

claireagordon added a commit to yext/JSON-java that referenced this issue Mar 26, 2024
See:
stleary/JSON-java#758
stleary/JSON-java#759

Port pull #759 from stleary/JSON-java to help
address OOM errors described in
https://www.cve.org/CVERecord?id=CVE-2023-5072

To support the JSONTokener.end() function this
relies on, port over the 'eof' flag & set in
all locations it's used in the latest JSON-java.

Use the String next(int n) implementation from
more recent java versions so we can properly check
end() while reading a group of characters.

Test by:
- importing into alpha locally & running all tests
that depend on //thirdparty:json
- verifying that Snyk's proof-of-concept does
not cause OOMs:
https://security.snyk.io/vuln/SNYK-JAVA-ORGJSON-5962464
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants