katzenpost / core

Core components common to clients and servers.
40 stars 11 forks source link

Decoding 9 bytes of bad CBOR data can exhaust memory (crypto/cert/cert.go) #96

Closed x448 closed 4 years ago

x448 commented 4 years ago

Decoding 9-10 bytes of malformed CBOR data can cause "fatal error: out of memory" and "runtime: out of memory" errors. Only 1 decode attempt is required to cause the error.

cc @david415 @muesli

Relevant Code

crypto/cert/cert.go

import (
... 
    "github.com/ugorji/go/codec"
...
)
...
// GetSignatures returns all the signatures.
func GetSignatures(rawCert []byte) ([]Signature, error) {
    cert := certificate{}
    dec := codec.NewDecoderBytes(rawCert, cborHandle)
    err := dec.Decode(&cert)
...
}

// GetSignature returns a signature that signs the certificate
// if it matches with the given identity.
func GetSignature(identity []byte, rawCert []byte) (*Signature, error) {
    cert := certificate{}
    dec := codec.NewDecoderBytes(rawCert, cborHandle)
    err := dec.Decode(&cert)

🔥 Error (fatal error: out of memory)

alt text

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

For more comparisons, see fxamacker/cbor.

Description and Minimal Reproduction

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 February 2020, smartcontractkit/chainlink reported an issue on pivitoltracker (I don't have login access) and fixed it in a GitHub PR titled "Switch to more secure CBOR library". They were also using same CBOR library as katzenpost/core.

To reproduce, decode 9-byte or 10-byte malformed CBOR data described in Section 8 of RFC 7049.

Examples of malformed CBOR data to achieve this can be found on GitHub since September 2019 (or possibly earlier if you look beyond Go projects).

david415 commented 4 years ago

Dear @x448 thanks for pointing this out! I've fixed it. Cheers!