Fix heap buffer overflow in AES key unwrap#133
Open
zandbelt wants to merge 1 commit into
Open
Conversation
Validate the encrypted_key length before AES_unwrap_key. The RFC 3394 wrapped key is always the plaintext CEK length plus 8 bytes; without this check an attacker-controlled, oversized encrypted_key is copied into the fixed-size jwe->cek buffer, overflowing it. Adds a regression test that imports a JWE whose encrypted_key segment has been replaced by an oversized blob and asserts that decryption fails with CJOSE_ERR_INVALID_ARG instead of overflowing. Signed-off-by: Hans Zandbelt <hans.zandbelt@openidc.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Summary
_cjose_jwe_decrypt_ek_aes_kw()passes the attacker-controlledencrypted_keysegment of an imported JWE straight to
AES_unwrap_key()without validating itslength.
AES_unwrap_key()writesencrypted_key_len - 8bytes into thefixed-size
jwe->cekbuffer (allocated for the expected CEK length of theencalgorithm), so an oversized
encrypted_keyoverflows that heap buffer.Impact
This is reachable pre-authentication via
cjose_jwe_import()+cjose_jwe_decrypt()on attacker-supplied input: a JWE using an AES Key Wrapalg(A128KW,A192KW,A256KW) with an over-longencrypted_keycauses aheap buffer overflow during decryption.
Root cause
The RFC 3394 wrapped key is always exactly the plaintext CEK length plus 8
bytes, but that invariant was never enforced before unwrapping:
Fix
Validate the wrapped-key length before calling
AES_unwrap_key():Testing
Adds
test_cjose_jwe_decrypt_aes_kw_oversized_ektotest/check_jwe.c: it buildsa valid AES-KW JWE, replaces the
encrypted_keysegment with an oversizedbase64url blob, and asserts that import still succeeds but
cjose_jwe_decrypt()fails with
CJOSE_ERR_INVALID_ARG(rather than overflowing). Covered forA128KW/A192KW/A256KWwith the AES-CBC-HMACencvalues andA256GCM.Full suite passes (
Checks: 77, Failures: 0, Errors: 0).References
Fixed in the maintained fork (OpenIDC/cjose, v0.6.2.5) and tracked in security
advisory
GHSA-75r7-f5cv-g3wj.