aporeto-inc / trireme-lib

Simple, scalable and secure application segmentation
https://trireme.io
Apache License 2.0
300 stars 51 forks source link

Decoding 9 bytes of bad CBOR data can exhaust memory (BinaryJWTClaims in controller/pkg/tokens/binaryjwt.go) #1001

Open x448 opened 4 years ago

x448 commented 4 years ago

Summary

Attempting to decode 9-10 bytes of malformed CBOR data (BinaryJWTClaims) causes
"fatal error: out of memory" or "runtime: out of memory" errors.

Only 1 decode attempt is needed to exhaust memory and cause these errors.

cc @sibicramesh @dstiliadis

Relevant code

trireme-lib/controller/pkg/tokens/binaryjwt.go

import (
...
"github.com/ugorji/go/codec"
...
)
...
func decode(buf []byte) (*BinaryJWTClaims, error) {
    // Decode the token into a structure.
    binaryClaims := &BinaryJWTClaims{}
    var h codec.Handle = new(codec.CborHandle)

    dec := codec.NewDecoderBytes(buf, h)
    if err := dec.Decode(binaryClaims); err != nil {

Actual behavior

Using the above decode function to decode 9-10 bytes of malformed CBOR data (BinaryJWTClaims) causes "fatal error: out of memory" or "runtime: out of memory" errors.

The malformed CBOR data simply needs to "lure a decoder into allocating very big data items (strings, arrays, maps) ..." as warned in RFC 7049 Section 8.

Expected behavior

One attempt to decode 9 bytes of malformed CBOR data (BinaryJWTClaims) should not be able to exhaust memory.

Steps to reproduce

Try to decode 9 bytes of malformed CBOR data described in RFC 7049 Section 8 (CBOR Security Considerations).

Examples of malformed CBOR data that can exhaust memory can be found on GitHub since September 2019 (possibly a lot earlier if you look beyond Go projects).

Solution proposal

trireme-lib should switch to a more secure CBOR library, which is what other projects did to fix this.

alt text

For more comparisons with ugorji/go, see fxamacker/cbor.

Background and Other Projects That Fixed This

In October 2013, RFC 7049 Section 8 (CBOR Security Considerations) warned that malformed CBOR data can be used to exhaust system resources.

Resource exhaustion attacks might attempt to lure a decoder into allocating very big data items (strings, arrays, maps) or exhaust the stack depth by setting up deeply nested items. Decoders need to have appropriate resource management to mitigate these attacks.

In Sept 2019, oasislabs/oasis-core discovered tiny malformed CBOR data can exhaust memory and they traced the problem to the same CBOR library being used by trireme-lib (ugorji/go). They fixed it by switching to a more secure CBOR library.

In Feb 2020, smartcontractkit/chainlink had a CBOR security issue which was fixed by
a GitHub PR titled "Switch to more secure CBOR library". They were also using the same CBOR library as trireme-lib.

For info about CBOR and security, see Section 8 of RFC 7049 (Security Considerations).

x448 commented 4 years ago

The old CBOR security comparison used malformed CBOR (discovered by oasislabs in September 2019) which only affects newer releases of ugorji/go.

New malformed CBOR data found in March 2020 exhausts memory and causes fatal error in all releases of ugorji/go from 1.1.0 to 1.1.7 as well as the last commit of ugorji/go.

As of April 7, 2020 the first non-beta release of ugorji/go is 1.1.0 and the last release is 1.1.7 and the last commit of ugorji/go is 42bc974 on August 12, 2019.

alt text