2

Recently, vulnerability reports are accumulating against (Java) libraries that complain that the library offers a recursive function that may exhaust the available stack depth and cause a StackOverflowError on "malicious" input. The newest example is CVE-2023-1370 complaining that a JSON parser may cause a StackOverflowError if it is requested to parse a nested object structure with a depth higher than the available stack size.

The vulnerability report claims that this behavior offers the possibility of a denial-of-service attack against software using this library. Isn't a StackOverflowError a regular exception that aborts the execution of the running request? When running e.g. in a web container, the request that caused the StackOverflowError is aborted, the failure is signaled with an error code - normally a HTTP/500 in case of such "internal" error and the thread that caused the error continues to serve the next request.

The "fix" for CVE-2023-1370 instead stops execution after reaching a fixed depth of 400 with a ParseException. Depending on the stack size and the size of the parser's stack frame size, this stops execution somewhat earlier, but the effect is more or less the same. The request with the "malicious" input is terminated, the error is signaled (here with a maybe somewhat "better" error message) and operation continues.

So why is it worth filing vulnerability reports against libraries with (almost all) recursive functions?

haui
  • 567
  • 5
  • 18
  • Code using the library would be expected to have handling for a ParseException but not necessarily a StackOverflowError. Unless it's doing a blanket catch everything. So the error can propagate further past the regular flow and error recovery mechanisms. Does that make sense? – teapot418 Mar 20 '23 at 07:47
  • @teapot418 - yes of cause a `ParseException` is more likely to be caught by "regular" error handling code, especially because it is a checked exception in this case. So a denial-of-service attack could theoretically succeed, if the `StackOverflowError` would hit the "main loop" of an application without a corresponding error handler. Since no Java server-framework should be affected by such a problem - is it really worth filing a CVE with severity "high" against a lib and enforcing an artificial limit on the JSON input that can be parsed? – haui Mar 20 '23 at 17:32
  • [Why is it a CVE](https://www.cve.org/ResourcesSupport/AllResources/CNARules#section_7_assignment_rules) - the author(s) of the library agreed that it is a problem or the reporter has proof of a real impact. [Why is it high?](https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator) network exploitable, low complexity, availability impact is probably enough for that. – teapot418 Mar 20 '23 at 19:01
  • I think my comments have crossed over to answer territory, let's make one. – teapot418 Mar 21 '23 at 09:10
  • Thanks for your research and pointers! – haui Mar 22 '23 at 14:20

1 Answers1

1

On a common sense level: any code using this library can reasonably be expected to have handling for a ParseException, but not a StackOverflowError, so this problem is going to make the code crash harder and give it less chance of recovering.

On a formalistic level:

Why is it a vulnerability: https://www.cve.org/ResourcesSupport/AllResources/CNARules#section_7_assignment_rules

  • the product owner (author) considers it to be a vulnerability
  • a CVA (CVE numbering authority) has judged it to be one
  • or there are reports of a real-world security impact

Why is it high: https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator

You can experiment with the metrics, I think network-exploitable, low-complexity, availability impact will do it.

teapot418
  • 1,239
  • 1
  • 3
  • 9
  • I agree a StackOverflowError would likely propagate further up the stack than a ParseException, but I still don't see how that justifies an A:H (High impact on Availability) CVSS rating. Unbounded heap memory consumption would crash or freeze a JVM, and deserve A:H, but not a single thread recursing too deeply. If you re-score this issue with A:N (no impact on availability), it gets a CVSS vector `AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N` which scores 0. This sounds appropriate to me. – Jonathan Fuerth Sep 01 '23 at 17:44