Skip to content

Strict mode for CBOR #2662

Open
Open
@timmc

Description

@timmc

What is your use-case and why do you need this feature?

My app needs to be able to sign and verify serialized data, which requires that the parse be unambiguous. The main problem is duplicate map keys. If there are repeated keys, then two recipients may disagree on what the signed data says, which is obviously a problem. :-) I've written on this kind of parser mismatch vulnerability previously: https://www.brainonfire.net/blog/2022/04/29/preventing-parser-mismatch/

The CBOR implementation currently accepts duplicate keys by using the last one encountered, but the spec says in §2.1:

A map that has duplicate keys may be well-formed, but it is not valid

§3.10 "Strict Mode" then waffles a bit and puts the onus on the sender to "avoid ambiguously decodable data" and defines an optional strict mode that decoders are not required to implement, particularly calling out duplicate key detection as a possibly heavy-weight requirement.

However, kotlinx.serialization already has the ability to detect duplicate keys because it builds up a HashMap or similar which can simply be consulted before insertion. (There's no streaming interface that I'm aware of.) The language in §3.10 is likely aimed at embedded and other highly constrained environments, which isn't particularly relevant to Kotlin.

Describe the solution you'd like

  1. Generally support rejection of repeated map keys, as an optional feature.
  2. Expose this as part of a new strict-mode feature in the Cbor implementation, enabled by default to comply with §2.1.

(I'd also love for the duplicate key rejection to be enabled by default for all formats, as this is a known vulnerability in many, many protocols and people should be protected by default—but still able to explicitly opt out of this protection if they know what they're doing. Major version bump, I know.)

Note: #1990 covers rejection of duplicate keys, but it wasn't clear if that was meant to be specific to JSON.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions