VYPR
High severity7.5NVD Advisory· Published Mar 5, 2024· Updated Apr 15, 2026

CVE-2024-24786

CVE-2024-24786

Description

The protojson.Unmarshal function can enter an infinite loop when unmarshaling certain forms of invalid JSON. This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
google.golang.org/protobufGo
< 1.33.01.33.0
google.golang.org/protobuf/encoding/protojsonGo
< 1.33.01.33.0
google.golang.org/protobuf/internal/encoding/jsonGo
< 1.33.01.33.0

Patches

1
f01a588e5810

encoding/protojson, internal/encoding/json: handle missing object values

4 files changed · +37 1
  • encoding/protojson/decode_test.go+17 0 modified
    @@ -2770,6 +2770,23 @@ func TestUnmarshal(t *testing.T) {
     		inputText:    `{"foo":{"bar":[{"baz":[{}]]}}`,
     		umo:          protojson.UnmarshalOptions{RecursionLimit: 5, DiscardUnknown: true},
     		wantErr:      "exceeded max recursion depth",
    +	}, {
    +		desc:         "Object missing value: no DiscardUnknown",
    +		inputMessage: &testpb.TestAllTypes{},
    +		inputText:    `{"":}`,
    +		umo:          protojson.UnmarshalOptions{RecursionLimit: 5, DiscardUnknown: false},
    +		wantErr:      `(line 1:2): unknown field ""`,
    +	}, {
    +		desc:         "Object missing value: DiscardUnknown",
    +		inputMessage: &testpb.TestAllTypes{},
    +		inputText:    `{"":}`,
    +		umo:          protojson.UnmarshalOptions{RecursionLimit: 5, DiscardUnknown: true},
    +		wantErr:      `(line 1:5): unexpected token`,
    +	}, {
    +		desc:         "Object missing value: Any",
    +		inputMessage: &anypb.Any{},
    +		inputText:    `{"":}`,
    +		wantErr:      `(line 1:5): unexpected token`,
     	}}
     
     	for _, tt := range tests {
    
  • encoding/protojson/well_known_types.go+4 0 modified
    @@ -322,6 +322,10 @@ func (d decoder) skipJSONValue() error {
     			if open > d.opts.RecursionLimit {
     				return errors.New("exceeded max recursion depth")
     			}
    +		case json.EOF:
    +			// This can only happen if there's a bug in Decoder.Read.
    +			// Avoid an infinite loop if this does happen.
    +			return errors.New("unexpected EOF")
     		}
     		if open == 0 {
     			return nil
    
  • internal/encoding/json/decode.go+1 1 modified
    @@ -121,7 +121,7 @@ func (d *Decoder) Read() (Token, error) {
     
     	case ObjectClose:
     		if len(d.openStack) == 0 ||
    -			d.lastToken.kind == comma ||
    +			d.lastToken.kind&(Name|comma) != 0 ||
     			d.openStack[len(d.openStack)-1] != ObjectOpen {
     			return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString())
     		}
    
  • internal/encoding/json/decode_test.go+15 0 modified
    @@ -1193,6 +1193,21 @@ func TestDecoder(t *testing.T) {
     				{E: errEOF},
     			},
     		},
    +		{
    +			in: `{""`,
    +			want: []R{
    +				{V: ObjectOpen},
    +				{E: errEOF},
    +			},
    +		},
    +		{
    +			in: `{"":`,
    +			want: []R{
    +				{V: ObjectOpen},
    +				{V: Name{""}},
    +				{E: errEOF},
    +			},
    +		},
     		{
     			in: `{"34":"89",}`,
     			want: []R{
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

11

News mentions

0

No linked articles in our index yet.