Repository navigation
Conversation
Token::from_bytes decodes attacker-supplied bytes, but the recursive map/array decoder trusted the input in two ways: - decode_array pre-allocated Vec::with_capacity(declared_len) straight from the array header, so a declared length near 2^64 panicked with a capacity overflow before any element was read. - Decoding recursed once per nesting level with no bound, so a header or payload nesting arrays/maps a few hundred thousand levels deep overflowed the stack and aborted the process. Reject a declared array or map length that the remaining input cannot hold (each array item needs at least one byte, each map entry two) before allocating or iterating, and cap container nesting at 32 levels (CWT/COSE/CAT structures nest only a few). Both return Error::InvalidFormat. Indefinite-length arrays and maps, which were misread as empty, are now rejected explicitly. The limits apply to the protected header, unprotected header and payload alike, and to every nested claim value. Add regression tests for each case in each position, and a cargo-fuzz target (fuzz/) for Token::from_bytes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| } | ||
| let array_len = dec.array()?; | ||
| let array_len = container_len(dec, array_len, 1, "array")?; | ||
| let mut array = Vec::with_capacity(array_len); |
There was a problem hiding this comment.
I think that assigning capacity like this can end up eating quite a bit of memory in the worst MAX_NESTING_DEPTH nested array case - is it worth considering Vec::new() instead?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Token::from_bytesdecodes untrusted input, but its recursive CBOR map/array decoder trusted two things from that input:decode_arraypre-allocatedVec::with_capacity(declared_len)straight from the array header, so a declared length near 2^64 panicked ("capacity overflow") before any element was read.Indefinite-length arrays and maps were also read as empty, which misparsed whatever followed.
Change
MAX_NESTING_DEPTH). CWT, COSE and CAT structures nest only a few.Error::InvalidFormat. The limits apply to the protected header, unprotected header and payload, and to every nested claim value. Valid tokens are unaffected, and the public API is unchanged.cargo-fuzztarget (fuzz/) exercisesToken::from_bytes,to_bytesandverify_claimson arbitrary input. It is excluded from the published crate.Tests
cargo clippy --all-targets -- -D warningsandcargo testpass, with 62 unit tests and 73 doctests.🤖 Generated with Claude Code