Skip to content

feat(ctap2): enforce authenticatorGetInfo limits before sending #254

@AlfioEmanueleFresta

Description

@AlfioEmanueleFresta

What's wrong

Ctap2GetInfoResponse (get_info.rs) deserializes maxMsgSize (0x05), maxCredentialCountInList (0x07), and maxCredentialIdLength (0x08), but nothing reads them. The builders Ctap2MakeCredentialRequest::from_webauthn_request (make_credential.rs) and Ctap2GetAssertionRequest::from_webauthn_request (get_assertion.rs) receive &Ctap2GetInfoResponse yet copy allowList/excludeList through unchanged. The client never drops over-long credential ids, never chunks by the count limit, and never bounds the request by maxMsgSize (1024 bytes when absent).

ctap2_preflight (preflight.rs) trims the allow list to one credential per probe, but only when C::supports_preflight() is true. Cable overrides it to false (CableChannel::supports_preflight()), so the full allow list goes in one getAssertion. excludeList is always sent in a single request, and even the post-preflight allow list can carry several entries.

Why it matters

Over-limit lists make the authenticator reject the whole ceremony (CTAP2_ERR_LIMIT_EXCEEDED, CTAP2_ERR_REQUEST_TOO_LARGE, CTAP1_ERR_INVALID_LENGTH) or get dropped by the transport, with opaque device-specific failures. An id longer than maxCredentialIdLength cannot belong to the authenticator, so it should be filtered client-side. This hurts most on hybrid/cable, which has no preflight to trim the list.

What to do

  • Add accessors on Ctap2GetInfoResponse for the three limits with spec defaults (maxMsgSize = 1024 when absent, the other two unbounded when absent).
  • Drop allow/exclude entries whose id length exceeds maxCredentialIdLength before sending.
  • Enforce maxCredentialCountInList: batch across requests where the flow allows, or return a typed error when a single required request cannot fit.
  • Bound the serialized CBOR by maxMsgSize, and fail before sending if it still exceeds after filtering.
  • Surface a typed error (new PlatformError variant in webauthn/error.rs) instead of relying on the CTAP status.
  • Apply the checks on both preflight and non-preflight paths in make_credential_fido2 and get_assertion_fido2 (webauthn.rs) so cable is covered.
  • Test oversized-id filtering, count batching and the count limit, and the maxMsgSize bound including the absent-field 1024 default.

Spec: CTAP 2.1/2.2 §6.4 authenticatorGetInfo.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions