CVE-2026-0994 Overview
A denial-of-service (DoS) vulnerability exists in google.protobuf.json_format.ParseDict() in Python, where the max_recursion_depth limit can be bypassed when parsing nested google.protobuf.Any messages. Due to missing recursion depth accounting inside the internal Any-handling logic, an attacker can supply deeply nested Any structures that bypass the intended recursion limit, eventually exhausting Python's recursion stack and causing a RecursionError.
Critical Impact
Remote attackers can crash Python applications using Protocol Buffers by sending specially crafted deeply nested Any messages, causing service disruption without authentication.
Affected Products
- Google Protocol Buffers (protobuf) Python library
- Applications using google.protobuf.json_format.ParseDict() function
- Services processing untrusted protobuf Any messages
Discovery Timeline
- 2026-01-23 - CVE CVE-2026-0994 published to NVD
- 2026-01-26 - Last updated in NVD database
Technical Details for CVE-2026-0994
Vulnerability Analysis
This vulnerability is classified under CWE-674 (Uncontrolled Recursion). The flaw resides in the JSON format parsing functionality of the Google Protocol Buffers Python library. When ParseDict() processes incoming data containing google.protobuf.Any message types, it fails to properly account for recursion depth within the internal Any-handling logic.
The max_recursion_depth parameter is designed to protect against stack exhaustion attacks by limiting how deeply nested structures can be parsed. However, the recursion counter is not decremented when the parser enters the Any message unpacking routine. This architectural oversight allows attackers to construct payloads that appear to respect the depth limit at the outer parsing layer while actually exceeding it through nested Any messages.
When exploited, the Python interpreter's call stack grows unbounded until it exceeds the system's recursion limit, triggering a RecursionError exception. If the application does not gracefully handle this exception, the entire process may crash, resulting in denial of service.
Root Cause
The root cause is missing recursion depth accounting inside the internal Any-handling logic of google.protobuf.json_format.ParseDict(). When the parser encounters an Any message and recursively calls itself to parse the contained message, it fails to decrement the current depth counter. This allows the effective recursion depth to exceed the configured max_recursion_depth limit, as each nested Any message essentially resets the depth counting.
Attack Vector
The attack vector is network-based, requiring no authentication or user interaction. An attacker can exploit this vulnerability by sending a specially crafted JSON payload to any endpoint that processes Protocol Buffer messages using the vulnerable ParseDict() function.
The attack payload consists of deeply nested google.protobuf.Any messages, where each Any contains another Any message. Since the recursion depth is not properly tracked through Any message boundaries, the parser continues processing until Python's stack limit is exceeded.
The vulnerability is exploited by constructing a deeply nested message structure where google.protobuf.Any messages are recursively embedded within each other. When this payload is passed to ParseDict(), the function recursively processes each nested Any message without properly tracking the recursion depth, eventually exhausting the Python call stack and raising a RecursionError. For technical implementation details, refer to the GitHub Pull Request for Protobuf.
Detection Methods for CVE-2026-0994
Indicators of Compromise
- Sudden application crashes with RecursionError exceptions in stack traces
- Log entries showing parsing failures in google.protobuf.json_format module
- Unusual increase in failed requests to endpoints processing protobuf messages
- Memory and CPU spikes preceding service termination
Detection Strategies
- Monitor application logs for RecursionError exceptions originating from protobuf parsing functions
- Implement request payload size and depth validation before passing to ParseDict()
- Deploy runtime application self-protection (RASP) to detect recursive parsing attacks
- Use SentinelOne's behavioral AI to identify abnormal process termination patterns
Monitoring Recommendations
- Configure alerting on application crashes with protobuf-related stack traces
- Monitor endpoint response times for degradation indicating parsing overhead
- Track the frequency of RecursionError exceptions across services
- Implement structured logging to capture payload characteristics before parsing
How to Mitigate CVE-2026-0994
Immediate Actions Required
- Review all services using google.protobuf.json_format.ParseDict() for exposure
- Implement input validation to reject payloads with excessive Any message nesting
- Add exception handling around ParseDict() calls to prevent cascading failures
- Consider rate limiting endpoints that process untrusted protobuf messages
Patch Information
The fix for this vulnerability is tracked in GitHub Pull Request #25239 for the Protocol Buffers repository. Organizations should monitor this pull request for merge status and update to the patched version once released. Check the official protobuf releases page for the security update.
Workarounds
- Implement custom pre-parsing validation to count nested Any message depth before calling ParseDict()
- Wrap ParseDict() calls in try-except blocks to catch RecursionError and return appropriate error responses
- Use a lower max_recursion_depth value as a defense-in-depth measure
- Deploy web application firewalls with rules to detect deeply nested JSON structures
# Configuration example
# Example: Implement defensive exception handling in Python
# Wrap ParseDict() calls with RecursionError handling
#
# try:
# message = json_format.ParseDict(data, proto_message, max_recursion_depth=50)
# except RecursionError:
# logging.error("Detected potential DoS attack via nested Any messages")
# return error_response("Invalid message structure")
#
# Additionally, consider implementing pre-validation of JSON depth
# before passing to ParseDict()
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


