Skip to content

Reject a malformed version message instead of panicking#107

Open
plaidfinch wants to merge 1 commit into
mainfrom
fix-version-panic
Open

Reject a malformed version message instead of panicking#107
plaidfinch wants to merge 1 commit into
mainfrom
fix-version-panic

Conversation

@plaidfinch

@plaidfinch plaidfinch commented Jul 17, 2026

Copy link
Copy Markdown

CAVEAT LECTOR: This PR was generated by Claude Fable 5.

Problem

The server parses the client's first attestation-protocol message with version_bytes[..4], which panics if the message body is shorter than 4 bytes. Any TLS-authenticated peer can trigger this with ~8 bytes (a length prefix of 2 followed by two bytes).

Fix

Parse the version with a checked conversion and reject anything but exactly 4 bytes as Error::ProtocolVersion.

One deliberate strictness change: a version message longer than 4 bytes was previously accepted with the trailing bytes ignored. No client of either protocol version has ever sent one (both send exactly CURRENT_PROTOCOL_VERSION.to_le_bytes()), so there is no interoperability change.

Testing

New regression test short_version_message_rejected: a TLS-authenticated client sends a 2-byte body; the server must return Err(ProtocolVersion) rather than panic.

Verified on illumos: cargo test 7/7, CI-style clippy clean.

Relationships

Independent of #108 and #109; the three can land in any order.

The server parsed the client's version message with version_bytes[..4],
which panics on a body shorter than 4 bytes — a remotely triggerable panic
for any TLS-authenticated peer, and process death under panic = "abort".
Parse with a checked conversion and reject anything but exactly 4 bytes as
Error::ProtocolVersion.

This is stricter than the old code in one way: a version message longer
than 4 bytes was previously accepted with the trailing bytes ignored. No
client has ever sent one (both protocol versions send exactly
CURRENT_PROTOCOL_VERSION.to_le_bytes()), so no interoperability change.
@hawkw

hawkw commented Jul 17, 2026

Copy link
Copy Markdown
Member

The combination of this change and #108 kinda makes me wonder if it might be valuable to have a version of recv_msg that's like recv_msg_exact<T, {const N: usize}> that returns a [u8; N] and rejects messages of greater length at the protocol level, and doesn't allocate a potentially arbitrarily-large Vec<u8>. I'd have to look closer at the surrounding code to see if there's more than exactly one place where we'd use that, though.

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