In the world of data interchange, JSON (JavaScript Object Notation) has become increasingly popular as a lightweight, human-readable data format. One widely used Python library for handling JSON data is orjson. However, prior to version 3.9.15, this library presented a security vulnerability concerning the recursion level, now identified as CVE-2024-27454.

In this post, we will explore the details of this vulnerability, illustrate how it can be exploited using a code snippet, provide links to original references, and discuss possible measures to address it.

Background

The orjson library leverages Rust for rapid JSON processing and provides convenient methods like loads and dumps for parsing and serializing JSON data. However, the orjson.loads function does not impose a recursion limit on deeply nested JSON documents before version 3.9.15. This oversight can lead to a denial-of-service (DoS) attack where threat actors exploit the vulnerability to cause a target system to become unresponsive or crash by processing an excessively nested JSON document.

Exploit Details

The issue lies in the fact that orjson.loads does not enforce any recursion depth limit while handling deeply nested JSON structures. This omission allows an attacker to craft an exceptionally nested JSON document and pass it to the vulnerable function. As a result, the target machine's stack overflows, leading to a crash or resource exhaustion. It is worth noting that Python's built-in json library enforces a default recursion limit, which is 100 or determined by the Python programming language maximum recursion depth (sys.getrecursionlimit()).

Code Snippet

To illustrate the vulnerability, we provide the following Python code snippet that demonstrates how an excessively nested JSON document can cause a stack overflow when processed with orjson.loads:

import orjson

# Craft a deeply nested JSON structure:
nested_json = '{"a":' * 100000 + '42' + '}' * 100000

# This line will cause a stack overflow if orjson version is < 3.9.15:
data = orjson.loads(nested_json)

print("Successfully parsed deeply nested JSON data:", data)

*Note: Running this code on a version of orjson prior to 3.9.15 may cause your system to crash or hang. Use at your own risk.*

Original References

1. The official GitHub repository for orjson, including documentation, can be found here: https://github.com/ijl/orjson
2. Details about the vulnerability can be viewed here: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-27454
3. The National Vulnerability Database (NVD) provides additional insights and information, accessible here: https://nvd.nist.gov/vuln/detail/CVE-2024-27454

Mitigation

The most effective way to mitigate this vulnerability is to upgrade your orjson library to version 3.9.15 or later. This release includes a patch ensuring that the orjson.loads function enforces a recursion limit while decoding nested JSON documents. To upgrade orjson, run the following command:

pip install --upgrade orjson

To manually impose a recursion limit, consider implementing a wrapper function around orjson.loads that counts and enforces depth during traversal. Alternatively, you could switch to Python's built-in json library, which has native recursion depth limits in place.

Conclusion

CVE-2024-27454 is a critical vulnerability affecting orjson versions before 3.9.15. By upgrading your installation or enforcing a recursion limit manually, you can secure your Python projects and protect them from potential denial-of-service attacks.

Timeline

Published on: 02/26/2024 16:28:00 UTC
Last modified on: 02/26/2024 16:32:25 UTC