basecamp/fizzy · error · ActionPack::WebAuthn::InvalidCborError
Input exceeds maximum size
Error message
Input exceeds maximum size
What it means
CborDecoder caps input at MAX_SIZE (10 megabytes by default) and raises InvalidCborError in initialize when bytes.length exceeds it. Real WebAuthn payloads are a few kilobytes, so hitting this limit almost always means the wrong byte string was passed or the decoder is being used on arbitrary user-supplied data.
Source
Thrown at lib/action_pack/web_authn/cbor_decoder.rb:102
MAX_SIZE = 10.megabytes
# Tags
POSITIVE_BIGNUM_TAG = 2
NEGATIVE_BIGNUM_TAG = 3
class << self
# Decodes a CBOR-encoded byte sequence into a Ruby object.
#
# ActionPack::WebAuthn::CborDecoder.decode("\xa2\x61a\x01\x61b\x02")
# # => {"a" => 1, "b" => 2}
def decode(bytes, **args)
bytes = bytes.bytes if bytes.respond_to?(:bytes)
new(bytes, **args).decode
end
end
def initialize(bytes, max_depth: MAX_DEPTH, max_size: MAX_SIZE) # :nodoc:
raise ActionPack::WebAuthn::InvalidCborError, "Input exceeds maximum size" if bytes.length > max_size
@bytes = bytes
@max_depth = max_depth
@position = 0
@depth = 0
end
# Decodes the next CBOR data item from the byte sequence.
def decode
raise ActionPack::WebAuthn::InvalidCborError, "Unexpected end of input" if @position >= @bytes.length
raise ActionPack::WebAuthn::InvalidCborError, "Maximum nesting depth exceeded" if @depth >= @max_depth
@depth += 1
result = case major_type
when UNSIGNED_INTEGER_TYPE then decode_unsigned_integer
when NEGATIVE_INTEGER_TYPE then decode_negative_integer
when BYTE_STRING_TYPE then decode_byte_stringView on GitHub (pinned to 7aabe74580)
Solutions
- Verify what you are decoding: in WebAuthn flows the input should be the attestation object or COSE key slice (bytes-to-kilobytes), never megabytes.
- If you legitimately decode large CBOR, raise the ceiling explicitly: CborDecoder.decode(bytes, max_size: 50.megabytes).
- Add a bytesize guard at the request boundary and reject oversized payloads with 413 before touching the decoder.
- Never pass request.body or file contents straight to the decoder without a size check.
Example fix
# before CborDecoder.decode(request.body.read) # after — bound the input explicitly bytes = request.body.read return head :payload_too_large if bytes.bytesize > 1.megabyte CborDecoder.decode(bytes)
Defensive patterns
Strategy: validation
Validate before calling
return head :payload_too_large if bytes.bytesize > ActionPack::WebAuthn::CborDecoder::MAX_SIZE value = ActionPack::WebAuthn::CborDecoder.decode(bytes)
Type guard
def within_cbor_size_limit?(bytes, limit = ActionPack::WebAuthn::CborDecoder::MAX_SIZE) bytes.respond_to?(:bytesize) ? bytes.bytesize <= limit : bytes.length <= limit end
Try / catch
begin
value = ActionPack::WebAuthn::CborDecoder.decode(bytes)
rescue ActionPack::WebAuthn::InvalidCborError => e
render json: { error: e.message }, status: :bad_request
end Prevention
- WebAuthn CBOR payloads are kilobytes — if yours approaches megabytes, you are decoding the wrong slice.
- Bound request bodies with a size guard (413) before parsing.
- Pass explicit max_size/max_depth when using the decoder outside WebAuthn so limits match your schema.
When it happens
Trigger: CborDecoder.decode with a payload over 10 MB — e.g. accidentally passing a whole uploaded file or a database blob instead of the attestationObject slice, or feeding the decoder raw request bodies in a generic CBOR endpoint.
Common situations: Custom (non-WebAuthn) use of the decoder on user uploads; a copy-paste bug that passes the full params hash serialized as bytes; denial-of-service probing where attackers pad CBOR input.
Related errors
- Unexpected end of input
- Maximum nesting depth exceeded
- Invalid base64 encoding in authenticator data
- 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/7d56a8e5246cd7a8.
Report an issue: GitHub.