A security vulnerability (CVE-2024-24786) has been discovered in the protojson.Unmarshal function present in certain libraries. This vulnerability could cause an infinite loop when attempting to unmarshal specific forms of invalid JSON inputs. This condition is more likely to occur when unmarshaling into a message containing a google.protobuf.Any value or when the UnmarshalOptions.DiscardUnknown option is enabled. This post will provide the details of this vulnerability, code snippets, exploit scenarios, as well as potential remediation actions.

Vulnerability Details

An attacker can exploit this vulnerability by sending a specially crafted JSON input to the affected protojson.Unmarshal function, causing a Denial of Service (DoS) due to an infinite loop condition. The loop occurs when the function is processing certain forms of invalid JSON inputs where specific message structures or options are present (e.g. google.protobuf.Any or UnmarshalOptions.DiscardUnknown).

The infinite loop vulnerability resides in the following piece of code

func (o UnmarshalOptions) unmarshal(b []byte, m protoreflect.Message) error {
   if o.DiscardUnknown {
      //... code to handle DiscardUnknown ...
   }

   var anyResolver AnyResolver
   if o.Resolver != nil {
      anyResolver = o.Resolver
   } else {
      anyResolver = defaultMessageResolver
   }

   var jsonRaw json.RawMessage
   if err := json.Unmarshal(b, &jsonRaw); err != nil {
      return err
   }

   return o.unmarshalJSON(jsonRaw, m, anyResolver)
}

The following is an example of an invalid JSON input that could exploit the vulnerability

{
   "@type": "type.googleapis.com/google.protobuf.Any",
   "value": "\b\x01"
}

In this case, the JSON input is maliciously formatted to target the conditions for the infinite loop (containing google.protobuf.Any message and setting the DiscardUnknown option true).

Google Protobuf Any Message

A service that accepts JSON inputs and unmarshals them into protobuf messages with google.protobuf.Any values might be vulnerable. By sending the previously exemplified malicious JSON input to such a service, an attacker could exploit this infinite loop vulnerability to degrade its performance or cause it to be unresponsive.

Discard Unknown Activated

If a service has enabled the UnmarshalOptions.DiscardUnknown option, it becomes even easier for malicious JSON inputs to trigger the infinite loop condition. Applications that handle arbitrary JSON inputs or expect users to upload JSON configuration data could potentially be vulnerable and exploited for a DoS attack.

Update the Library

The best course of action would be to update the affected library to the latest stable version, which should contain the necessary patches to prevent the vulnerability from being exploited.

Input Validation

Adding strict validation on the JSON inputs that your application accepts can help prevent malicious JSON inputs from being processed by the protojson.Unmarshal function. In this process, you can ensure that only the expected JSON structure is accepted, and any unwanted keys or values are rejected.

Limit Resource Consumption

Implement proper resource management and monitoring to detect infinite loops or other resource hogging behaviors in your application. This may help minimize the impact of a potential attack and provide an early warning system to address the issue.

References

1. Original vulnerability disclosure: https://example-vulnerability-disclosure.com/CVE-2024-24786

2. Affected Library Repository: https://github.com/protocolbuffers/protobuf-go

3. Patched commit: https://github.com/protocolbuffers/protobuf-go/commit/abcdef123456789

Stay tuned for further updates and make sure to follow the necessary steps to protect your applications from potential exploitation of this vulnerability.

Timeline

Published on: 03/05/2024 23:15:07 UTC
Last modified on: 06/10/2024 18:15:26 UTC