Skip to content

Commit a65725d

Browse files
authored
Cap uncompressed length in TLS Certificate Compression (#13117)
* Cap uncompressed length in TLS Certificate Compression * Set a nullptr * Update the comment
1 parent 571ee72 commit a65725d

4 files changed

Lines changed: 27 additions & 0 deletions

File tree

src/iocore/net/TLSCertCompression.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
#include <vector>
2828
#include <string>
2929

30+
// RFC 8879 uses uint24 for uncompressed_length, allowing up to ~16 MB.
31+
// Real certificate chains rarely exceed 10-30 KB even with large RSA
32+
// keys and multiple intermediates — 128 KB gives ample headroom while
33+
// preventing excessive memory allocation from a malicious peer.
34+
constexpr size_t MAX_CERT_UNCOMPRESSED_LEN = 128 * 1024;
35+
3036
/**
3137
* Common function to set certificate compression preference
3238
*

src/iocore/net/TLSCertCompression_brotli.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323

2424
#include "TLSCertCompression_brotli.h"
25+
#include "TLSCertCompression.h"
2526
#include "SSLStats.h"
2627
#include <openssl/ssl.h>
2728
#include <brotli/decode.h>
@@ -55,6 +56,12 @@ compression_func_brotli(SSL * /* ssl */, CBB *out, const uint8_t *in, size_t in_
5556
int
5657
decompression_func_brotli(SSL * /* ssl */, CRYPTO_BUFFER **out, size_t uncompressed_len, const uint8_t *in, size_t in_len)
5758
{
59+
if (uncompressed_len > MAX_CERT_UNCOMPRESSED_LEN) {
60+
*out = nullptr;
61+
Metrics::Counter::increment(ssl_rsb.cert_decompress_brotli_failure);
62+
return 0;
63+
}
64+
5865
uint8_t *buf;
5966

6067
*out = CRYPTO_BUFFER_alloc(&buf, uncompressed_len);

src/iocore/net/TLSCertCompression_zlib.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323

2424
#include "TLSCertCompression_zlib.h"
25+
#include "TLSCertCompression.h"
2526
#include "SSLStats.h"
2627
#include <openssl/ssl.h>
2728
#include <zlib.h>
@@ -53,6 +54,12 @@ compression_func_zlib(SSL * /* ssl */, CBB *out, const uint8_t *in, size_t in_le
5354
int
5455
decompression_func_zlib(SSL * /* ssl */, CRYPTO_BUFFER **out, size_t uncompressed_len, const uint8_t *in, size_t in_len)
5556
{
57+
if (uncompressed_len > MAX_CERT_UNCOMPRESSED_LEN) {
58+
*out = nullptr;
59+
Metrics::Counter::increment(ssl_rsb.cert_decompress_zlib_failure);
60+
return 0;
61+
}
62+
5663
uint8_t *buf;
5764

5865
*out = CRYPTO_BUFFER_alloc(&buf, uncompressed_len);

src/iocore/net/TLSCertCompression_zstd.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323

2424
#include "TLSCertCompression_zstd.h"
25+
#include "TLSCertCompression.h"
2526
#include "SSLStats.h"
2627
#include <openssl/ssl.h>
2728
#include <zstd.h>
@@ -60,6 +61,12 @@ compression_func_zstd(SSL * /* ssl */, CBB *out, const uint8_t *in, size_t in_le
6061
int
6162
decompression_func_zstd(SSL * /* ssl */, CRYPTO_BUFFER **out, size_t uncompressed_len, const uint8_t *in, size_t in_len)
6263
{
64+
if (uncompressed_len > MAX_CERT_UNCOMPRESSED_LEN) {
65+
*out = nullptr;
66+
Metrics::Counter::increment(ssl_rsb.cert_decompress_zstd_failure);
67+
return 0;
68+
}
69+
6370
uint8_t *buf;
6471

6572
*out = CRYPTO_BUFFER_alloc(&buf, uncompressed_len);

0 commit comments

Comments
 (0)