Skip to content

Commit 078464b

Browse files
committed
ReadRawBytes: avoid huge memory allocations
A call to this method could previously reserve any amount of memory, e.g., by parsing some malicious CBOR string. This kind of resource exhaustion attack is now mitigated by using some buffers for larger amounts of data.
1 parent ee860ab commit 078464b

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

strings.go

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
11
package cboring
22

33
import (
4+
"bytes"
45
"fmt"
56
"io"
7+
"math"
68
)
79

810
// ReadRawBytes reads the next l bytes from r into a new byte slice.
911
func ReadRawBytes(l uint64, r io.Reader) (data []byte, err error) {
10-
data = make([]byte, l)
11-
_, err = io.ReadFull(r, data)
12+
if l > math.MaxInt32 {
13+
err = fmt.Errorf("cannot read %d raw bytes, is greater than max int32", l)
14+
return
15+
}
16+
17+
// The following code is a compromise. Data up to one megabyte is cached in memory. However, larger data will be
18+
// copied in a temporary buffer, which is finally accessed. This is primarily a mitigation against resource
19+
// exhaustion attacks with constructed CBOR strings which indicate to contain a huge payload.
20+
if l <= 1024*1024 {
21+
data = make([]byte, l)
22+
_, err = io.ReadFull(r, data)
23+
} else {
24+
var buf bytes.Buffer
25+
if _, err = io.CopyN(&buf, r, int64(l)); err == nil {
26+
data = buf.Bytes()
27+
}
28+
}
29+
1230
return
1331
}
1432

0 commit comments

Comments
 (0)