When using Python for fast JSON processing, the orjson library is a popular, high-performance choice. But recently, researchers uncovered a critical flaw, CVE-2024-27454, in orjson versions before 3.9.15. This post will clearly explain what that is, how it can be exploited, with code examples, and what you should do right now if you use orjson.
What is CVE-2024-27454?
Summary:
orjson’s orjson.loads function, up to version 3.9.15, does not properly limit recursion. This means if you hand it a crafted, deeply nested JSON document, it can get stuck in very deep or infinite recursion. This can lead to:
In some cases, resource exhaustion (CPU, stack, memory)
If you accept user input that gets passed to orjson.loads, your service might be vulnerable to remote crash or slowdowns.
Reference:
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2024-27454
- GitHub Security Advisory: https://github.com/ijl/orjson/security/advisories/GHSA-v693-mhrq-7pjv
How Does the Exploit Work?
In many JSON parsers, there’s a built-in limit to how deeply JSON objects and arrays can nest, to avoid risks of stack overflows from "evil" inputs. For example, Python’s standard json module has a default recursion limit.
But:
Until version 3.9.15, orjson has no such recursion limit. That means you can send data like this which, when parsed, causes Python’s C stack to fill up and trigger a crash.
Here’s how you can create a payload to trigger this issue
import orjson
# Let's build a JSON string that's deeply nested:
def make_deep_json(depth):
s = ''
for _ in range(depth):
s += '{"a":'
s += '1'
s += '}' * depth
return s
deep_json = make_deep_json(500) # 500 is often enough to cause trouble!
# This will likely crash or hang orjson, Python, or your process:
orjson.loads(deep_json)
On a vulnerable orjson version:
You’ll probably see a RecursionError, or maybe even a segmentation fault (crash). If this happens in a server context, your whole API might go down!
Why Does This Matter?
If you provide any public or semi-public API endpoint that decodes user JSON and you’re using orjson <3.9.15, your service can be crashed remotely with this simple trick.
Real Attack Scenarios
- A web API accepting JSON POST bodies (think Flask/FastAPI/Starlette + orjson).
Mitigation: What Should You Do?
TL;DR:
Upgrade orjson to 3.9.15 or newer, _immediately_.
pip install --upgrade orjson
or pin it in your requirements
orjson>=3.9.15
After update:
The library will now refuse to parse overly-deep inputs, so you’re safe from stack attacks.
Workarounds (if you absolutely can’t upgrade)
- Validate incoming JSON with a safer parser (such as the standard json module which can limit recursion).
- Pre-filter payload size/complexity.
Set Python’s recursion limit lower (not bulletproof: sys.setrecursionlimit).
But upgrading is by far the safest and easiest method!
References & Further Reading
- orjson’s Security Advisory (GitHub)
- NVD’s CVE Alert
Conclusion
CVE-2024-27454 is a great example of how libraries for speed can sometimes skip important guardrails. If you use orjson, update now—don’t let attackers crash your app with nothing more than a long string of {.
If you build or maintain Python APIs, always watch out for similar parser recursion limits!
Timeline
Published on: 02/26/2024 16:28:00 UTC
Last modified on: 02/26/2024 16:32:25 UTC