{"record":{"id":"7d56a8e5246cd7a8","repo":"basecamp/fizzy","slug":"input-exceeds-maximum-size","errorCode":null,"errorMessage":"Input exceeds maximum size","messagePattern":"Input exceeds maximum size","errorType":"exception","errorClass":"ActionPack::WebAuthn::InvalidCborError","httpStatus":null,"severity":"error","filePath":"lib/action_pack/web_authn/cbor_decoder.rb","lineNumber":102,"sourceCode":"  MAX_SIZE = 10.megabytes\n\n  # Tags\n  POSITIVE_BIGNUM_TAG = 2\n  NEGATIVE_BIGNUM_TAG = 3\n\n  class << self\n    # Decodes a CBOR-encoded byte sequence into a Ruby object.\n    #\n    #   ActionPack::WebAuthn::CborDecoder.decode(\"\\xa2\\x61a\\x01\\x61b\\x02\")\n    #   # => {\"a\" => 1, \"b\" => 2}\n    def decode(bytes, **args)\n      bytes = bytes.bytes if bytes.respond_to?(:bytes)\n      new(bytes, **args).decode\n    end\n  end\n\n  def initialize(bytes, max_depth: MAX_DEPTH, max_size: MAX_SIZE) # :nodoc:\n    raise ActionPack::WebAuthn::InvalidCborError, \"Input exceeds maximum size\" if bytes.length > max_size\n\n    @bytes = bytes\n    @max_depth = max_depth\n    @position = 0\n    @depth = 0\n  end\n\n  # Decodes the next CBOR data item from the byte sequence.\n  def decode\n    raise ActionPack::WebAuthn::InvalidCborError, \"Unexpected end of input\" if @position >= @bytes.length\n    raise ActionPack::WebAuthn::InvalidCborError, \"Maximum nesting depth exceeded\" if @depth >= @max_depth\n\n    @depth += 1\n\n    result = case major_type\n    when UNSIGNED_INTEGER_TYPE then decode_unsigned_integer\n    when NEGATIVE_INTEGER_TYPE then decode_negative_integer\n    when BYTE_STRING_TYPE then decode_byte_string","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/basecamp/fizzy/blob/7aabe7458060d8a1759a53b7ede39e74e6c0b20d/lib/action_pack/web_authn/cbor_decoder.rb#L84-L120","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nCborDecoder.decode(request.body.read)\n\n# after — bound the input explicitly\nbytes = request.body.read\nreturn head :payload_too_large if bytes.bytesize > 1.megabyte\nCborDecoder.decode(bytes)","handlingStrategy":"validation","validationCode":"return head :payload_too_large if bytes.bytesize > ActionPack::WebAuthn::CborDecoder::MAX_SIZE\nvalue = ActionPack::WebAuthn::CborDecoder.decode(bytes)","typeGuard":"def within_cbor_size_limit?(bytes, limit = ActionPack::WebAuthn::CborDecoder::MAX_SIZE)\n  bytes.respond_to?(:bytesize) ? bytes.bytesize <= limit : bytes.length <= limit\nend","tryCatchPattern":"begin\n  value = ActionPack::WebAuthn::CborDecoder.decode(bytes)\nrescue ActionPack::WebAuthn::InvalidCborError => e\n  render json: { error: e.message }, status: :bad_request\nend","preventionTips":["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."],"tags":["cbor","input-validation","size-limit","webauthn"],"backgroundTag":"payload-too-large","analyzedSha":"7aabe7458060d8a1759a53b7ede39e74e6c0b20d","analyzedAt":"2026-08-21T18:33:25.349Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}