diff --git a/security-advisories/2021-09-30-0-cpu-amplification.md b/security-advisories/2021-09-30-0-cpu-amplification.md new file mode 100644 index 0000000..d0be8a6 --- /dev/null +++ b/security-advisories/2021-09-30-0-cpu-amplification.md @@ -0,0 +1,57 @@ +Problem +======= + +CPU usage amplification attack + +Discovered by +============= + +Martin Dindoffer <contact@dindoffer.eu> + +Announced +========= + +2021-09-30 + +Impact +====== + +It is possible for an attacker to craft a small malicious message that will contain large lists with no data, leading to +artificial load on the system and possibly a Denial of Service attack. + +CVSS score +========== + +5.9 (Medium) CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H + +Fixed in +======== + +Release 0.1.11 + +Details +======= + +Cap'n'Proto List pointer encodes the size of the list in the header as a 29 bit value. This value is read as a counter +for the list Iterator. Setting a large value for the elementCount may produce empty loops in the code that don't operate +on any data but still consume CPU time. + +List Amplification is a well known posibility in the Cap'n'Proto protocol, as can be seen in the Encoding +spec (https://capnproto.org/encoding.html): +> A list of Void values or zero-size structs can have a very large element count while taking constant space on the wire. +> If the receiving application expects a list of structs, it will see these zero-sized elements as valid structs set to their default values. +> If it iterates through the list processing each element, it could spend a large amount of CPU time or other resources despite the message being small. +> To defend against this, the “traversal limit” should count a list of zero-sized elements as if each element were one word instead. +> This rule was introduced in the C++ implementation in commit 1048706. + +A form of this traversal limit countermeasure is present in capnproto-java. However, the message may contain a huge list +with 1-bit elements that are read as a struct list. This combined with the fact that the data may simply be stripped +from the message makes it is possible to create problematically huge Iterators with default traversal limits. + +Remediation +=========== + +The iteration should take into account the actual message length. As a rule of thumb the parser should not enter loops +with an attacker-controlled iteration count that is not bounded by the input length. + +Therefore additional bounds checking was introduced to detect out-of-bounds list pointers. \ No newline at end of file diff --git a/security-advisories/2021-09-30-1-excessive-memory-allocation.md b/security-advisories/2021-09-30-1-excessive-memory-allocation.md new file mode 100644 index 0000000..2f54aca --- /dev/null +++ b/security-advisories/2021-09-30-1-excessive-memory-allocation.md @@ -0,0 +1,54 @@ +Problem +======= + +Insufficient validation of message metadata with negative segment sizes may lead to excessive memory allocation and +subsequent DoS. + +Discovered by +============= + +Martin Dindoffer <contact@dindoffer.eu> + +Announced +========= + +2021-09-30 + +Impact +====== + +It is possible for an attacker to craft a malicious message that may thanks to memory amplification lead to a Denial of +Service attack against the consumer of CapnProto messages. In practical terms a message of only 8 bytes may cause +allocation of 2GB of memory. + +CVSS score +========== + +7.5 (High) CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H + +Fixed in +======== + +Release 0.1.11 + +Details +======= + +A read of 4 bytes from the message is performed, the result of which is read as the size of a segment in a variable. +This size is stored in memory as a signed integer. If the segment count is 1, the size of the first segment is also +considered to be the total size of the message stored in a totalWords variable. Since both the segment0Size and the +totalWords are signed integers, they may hold a negative number which will pass the traversal limit check. + +Subsequently capnproto-java tries to allocate enough memory for the segment. Because the encoded size is in words, the +value is multiplied by the number 8. The resulting number is used as the size of a ByteBuffer allocated for the first +segment. A sufficiently large negative number when multiplied by 8 will net a large positive integer, thus causing large +memory allocation in the form of a ByteBuffer. + +A segment size of `-1 879 048 193` multiplied by 8 results in `2 147 483 640` bytes of allocated memory, which is close +to `Integer.MAX_VALUE` and around the size of the maximum length of a Java array. Therefore the maximum size a message +may allocate this way is roughly 2GB. + +Remediation +=========== + +Stricter validation refusing negative segment sizes was implemented. \ No newline at end of file diff --git a/security-advisories/2021-10-04-0-cpu-amplification.md b/security-advisories/2021-10-04-0-cpu-amplification.md new file mode 100644 index 0000000..cd23609 --- /dev/null +++ b/security-advisories/2021-10-04-0-cpu-amplification.md @@ -0,0 +1,47 @@ +Problem +======= + +Incorrect parsing of large list element sizes may lead to CPU usage amplification attack + +Discovered by +============= + +Martin Dindoffer <contact@dindoffer.eu> + +Announced +========= + +2021-10-04 + +Impact +====== + +It is possible for an attacker to craft a small malicious message that will contain large lists with no data, leading to +artificial load on the system and possibly a Denial of Service attack. + +CVSS score +========== + +5.9 (Medium) CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H + +Fixed in +======== + +Release 0.1.12 + +Details +======= + +A tag pointer encodes the size of the elements in words and the total number of elements. Validation of these values is +performed in the code, but only as an overflow check of their product (against the total wordcount encoded in the list +pointer). The element size is read as a `short` value with improper casting to signed integers. Therefore, it is +possible to craft a message that will encode a large amount of elements (up to `2^30`) and offset this bloated size by +specifying a negative size of the elements (in words). There is no need to encode the actual payload for the large list, +thus capnproto-java will generate Iterators with large iteration counts over empty payload with messages of well under +100 bytes, that may put CPU under loads heavy enough to easily perform DoS attacks. + +Remediation +=========== + +The `short` values of the list element sizes are now parsed as unsigned values, making sure that the list overflow check +will catch the huge list size. \ No newline at end of file