chatmail / chatmail/filtermail
Possible fix(deps): rustls-webpki 0.103.11 → 0.103.13, 0.104.0-alpha.7 (GHSA-82j2-j2ch-gfr8) in Cargo.lock
- Dominant language
- Rust
- Stars
- 11
- Forks
- 4
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 17
Description
I think there may be a problem in `Cargo.lock` around line 1972.
HIGH-severity remote DoS (process panic) in rustls-webpki 0.103.11 (GHSA-82j2-j2ch-gfr8). `bit_string_flags()` in src/der.rs parses named-bit BIT STRINGs (e.g., the onlySomeReasons field of the issuingDistributionPoint CRL extension) and indexes `raw_bits[raw_bits.len() - 1]` without handling the case where padding_bits == 0 and the bit-string body is empty. A BIT STRING whose content is exactly [0x00] passes both guards, so `raw_bits.len() - 1` underflows 0usize to usize::MAX and the slice index panics (debug: 'attempt to subtract with overflow'; release: 'index out of bounds: the len is 0 but the index is 18446744073709551615'). This is reachable from the public API `BorrowedCertRevocationList::from_der()` with a ~103-byte crafted CRL. Impact is availability only — a Rust panic unwinds/aborts safely, so there is no memory corruption or RCE — but any attacker who can control the CRL bytes fed to the process can deterministically crash it. Exploitation requires that the application (1) explicitly opts into revocation checking by passing RevocationOptions to verify_for_usage(), and (2) loads CRLs from an attacker-influenced source; the realistic path is an mTLS server that fetches a CRL distribution point (CDP) URL embedded in a client certificate the attacker owns, or a TLS client whose server-cert CDP fetch is MITM'd. Default rustls configurations without RevocationOptions are not affected. Risk: HIGH — a single small payload causes a hard process crash during certificate-chain validation, i.e., trivially weaponizable denial of service for CRL-checking deployments. Remediation: upgrade rustls-webpki to the fixed release 0.103.13 (or 0.104.0-alpha.7) in Cargo.lock; no code workaround exists other than patching der.rs directly.
Something like this might fix it:
````diff
1) Preferred fix — upgrade the dependency (ships the upstream fix for der.rs). Run in the repository root:
cargo update -p rustls-webpki --precise 0.103.13
Resulting Cargo.lock change (finding at lines 1972-1982):
```diff
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1972,8 +1972,8 @@
[[package]]
name = "rustls-webpki"
-version = "0.103.11"
+version = "0.103.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = ""
+checksum = ""
```
Do not hand-edit the checksum — let `cargo update` pull it from crates.io, then rebuild and re-scan to confirm the finding clears. If you track the 0.104 alpha line, bump to 0.104.0-alpha.7 instead.
2) Reference code fix (what the upgrade contains; apply directly only if hot-fixing a vendored copy). Make the empty-bit-string case non-panicking by rejecting it as a DER error instead of indexing an empty slice:
```diff
--- a/src/der.rs
+++ b/src/der.rs
@@ fn bit_string_flags(bytes: untrusted::Input<'a>) -> Result, Error>
- if padding_bits > 7 || (raw_bits.is_empty() && padding_bits != 0) {
- return Err(Error::BadDer);
- }
- let last_byte = raw_bits[raw_bits.len() - 1]; // panics when raw_bits is empty and padding_bits == 0
+ // An empty named-bit string (BIT STRING content [0x00]: padding byte 0x00,
+ // zero data bytes) previously underflowed `len() - 1` to usize::MAX and
+ // panicked (GHSA-82j2-j2ch-gfr8). Reject it as malformed DER instead.
+ if padding_bits > 7 || raw_bits.is_empty() {
+ return Err(Error::BadDer);
+ }
+ // Safe: raw_bits is guaranteed non-empty here.
+ let last_byte = raw_bits[raw_bits.len() - 1];
```
Equivalent one-line alternative that removes the panic regardless of guard ordering:
```diff
- let last_byte = raw_bits[raw_bits.len() - 1];
+ let Some(last_byte) = raw_bits.last().copied() else { return Err(Error::BadDer); };
```
Behavioral note: this treats an empty named-bit list as BadDer (it carries no flags), which is safe for webpki's consumers (KeyUsage/ReasonFlags checks then simply fail validation rather than crashing). Add a regression test parsing the PoC CRL from the advisory through `BorrowedCertRevocationList::from_der()` and asserting it returns Err rather than panicking.
````
For reference: rule `GHSA-82j2-j2ch-gfr8`. Rated high.
The suggested change is untested against this project, so please read it before applying it.
---
*Found with automated scanning ([RedGem](https://code.redgem.net)) and reviewed before opening. If it is not useful, closing it is completely fine.*
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in the repository root by inspecting Cargo.lock around the rustls-webpki entry near line 1972, then run the proposed cargo update command. Rebuild the project and re-scan to confirm the advisory is cleared; if adding coverage, exercise the supplied PoC through BorrowedCertRevocationList::from_der() and verify it returns an error rather than panicking.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- security
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100