basecamp/fizzy · error · ActionPack::WebAuthn::InvalidCborError
Reserved additional info: #{info}
Error message
Reserved additional info: #{info} What it means
read_argument decodes the length/argument that follows a CBOR header byte. Additional-info values 28–30 are reserved by RFC 8949 for future standardization and no conformant encoder emits them; encountering one means the header byte is corrupt, so the decoder raises InvalidCborError with the reserved value.
Source
Thrown at lib/action_pack/web_authn/cbor_decoder.rb:235
Math.ldexp(mantissa, -24)
elsif exponent == 31
mantissa == 0 ? Float::INFINITY : Float::NAN
else
Math.ldexp(mantissa + 1024, exponent - 25)
end
sign == 1 ? -value : value
end
def read_argument
case info = additional_info
when SIMPLE_VALUE_RANGE then info
when SINGLE_BYTE_VALUE_FOLLOWS then read_byte
when TWO_BYTE_VALUE_FOLLOWS then read_bytes(2).pack("C*").unpack1("n")
when FOUR_BYTE_VALUE_FOLLOWS then read_bytes(4).pack("C*").unpack1("N")
when EIGHT_BYTE_VALUE_FOLLOWS then read_bytes(8).pack("C*").unpack1("Q>")
when RESERVED_VALUE_RANGE
raise ActionPack::WebAuthn::InvalidCborError, "Reserved additional info: #{info}"
else
raise ActionPack::WebAuthn::InvalidCborError, "Invalid additional info: #{info}"
end
end
def additional_info(consume: true)
byte = consume ? read_byte : peek
byte & 0b00011111
end
def indefinite_length?
read_byte if additional_info(consume: false) == INDEFINITE_LENGTH_MAJOR_TYPE
end
def break_code?
read_byte if peek == BREAK_CODE
end
View on GitHub (pinned to 7aabe74580)
Solutions
- Hex-dump the input and check the failing offset's header byte — low 5 bits in 28..30 confirm corruption.
- Re-encode the payload with a standard CBOR library rather than patching bytes.
- Rescue ActionPack::WebAuthn::InvalidCborError once at the call site and reject the payload with 400.
- Add an integrity check (HMAC or signature verification happens anyway in WebAuthn) before parsing to discard tampered input early.
Example fix
# before value = ActionPack::WebAuthn::CborDecoder.decode(bytes) # after — single choke point for every CBOR syntax error (reserved info, bad lengths, truncation) def decode_cbor(bytes) ActionPack::WebAuthn::CborDecoder.decode(bytes) rescue ActionPack::WebAuthn::InvalidCborError raise ApplicationController::BadRequest, 'malformed CBOR payload' end
Defensive patterns
Strategy: try-catch
Try / catch
begin
value = ActionPack::WebAuthn::CborDecoder.decode(bytes)
rescue ActionPack::WebAuthn::InvalidCborError => e
render json: { error: 'malformed CBOR payload' }, status: :bad_request
end Prevention
- Verify payload integrity (signature/HMAC) before parsing; tampered bytes surface as reserved-info errors.
- Transport CBOR as binary; avoid text pipelines that can flip bytes.
- Use one central rescue for all InvalidCborError variants and map to 400.
When it happens
Trigger: A header byte whose low 5 bits are 28/29/30 (e.g. 0x9C, 0x9D, 0x9E for text strings) anywhere a length argument is read — result of random corruption, fuzzing, or mis-copied byte strings.
Common situations: Bit-rot or transmission errors in binary payloads; hand-assembled CBOR where a length was written as the raw value instead of an encoded argument; concatenating CBOR fragments mid-item.
Related errors
- Invalid simple value: #{info}
- Invalid additional info: #{info}
- Unexpected end of input
- Authenticator data is too short
- Authenticator data is too short for attested credential data
AI-assisted analysis of basecamp/fizzy@7aabe74580 (2026-08-21).
Data as JSON: /api/errors/dd55a43f7f30f133.
Report an issue: GitHub.