Description
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
- Generally support rejection of repeated map keys, as an optional feature.
- 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.