Skip to content

fix(quic): reject oversized Retry tokens#8

Open
alanhoff wants to merge 1 commit intoendel:mainfrom
alanhoff:fix/retry-token-plaintext-bounds
Open

fix(quic): reject oversized Retry tokens#8
alanhoff wants to merge 1 commit intoendel:mainfrom
alanhoff:fix/retry-token-plaintext-bounds

Conversation

@alanhoff
Copy link
Copy Markdown

Summary

  • reject Retry tokens whose encoded size exceeds the implementation's fixed plaintext capacity before attempting AEAD decryption
  • keep validateRetryToken() aligned with TOKEN_MAX_PLAINTEXT_LEN / TOKEN_MAX_LEN
  • add a regression test that exercises an oversized token length and expects clean rejection

Vulnerability

This Retry token format is implemented as:

  • nonce: 12 bytes
  • encrypted plaintext: up to 64 bytes
  • tag: 16 bytes

That means the largest valid Retry token for this implementation is 92 bytes. Before this change, validateRetryToken() only checked the minimum token size, then derived ct_len from the attacker-controlled token length and immediately sliced plaintext[0..ct_len] for AES-GCM decryption.

A remote peer could therefore send an Initial packet carrying an oversized Retry token, for example:

  • 93 bytes total token length, which makes ct_len = 65 and already exceeds the 64-byte plaintext buffer
  • a much larger token (for example 256 or 512 bytes), which drives the same out-of-bounds slice even further

In safe builds that panics during validation; in unchecked builds it risks writing past the fixed stack buffer in this network-facing token parser.

Validation

  • zig build test
  • zig build
  • zig build fuzz

References

Return early when a Retry token exceeds the implementation's fixed plaintext capacity so decryption never slices past the local stack buffer. Add a regression test that exercises an oversized token length and expects clean rejection.

Co-authored-by: Codex <noreply@openai.com>
Copilot AI review requested due to automatic review settings March 17, 2026 20:25
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens QUIC Retry token validation by rejecting tokens larger than the implementation’s fixed capacity before any slicing/decryption occurs, preventing a potential out-of-bounds slice during AES-GCM decrypt.

Changes:

  • Add an upper-bound length check in validateRetryToken() to reject tokens larger than TOKEN_MAX_LEN.
  • Add an explicit ciphertext-length bound check (ct_len <= TOKEN_MAX_PLAINTEXT_LEN) before slicing/decrypt.
  • Add a regression test ensuring oversized Retry tokens are cleanly rejected (no panic).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants