Hi Mauro, I prefer using tag-value-pairs instead of more-or-less complex JSON-objects, because it will preserve the O(n) parsing efficiency. Since the Working Group already decided to introduce JSON, I just suggested the flat array approach.
Regards, Timo It looks like Mauro De Gennaro aimed to say: > Hi Timo, > > Before we continue discussing JSON parsing performance and security concerns, > could you clarify your underlying motivation for replacing the current > tag=value design with JSON, given that you yourself have raised concerns > about JSON's issues? My apologies if this was addressed in an earlier thread > I may have missed. > > As you know, the latest DKIM2 draft uses JSON only within the recipes, and > your proposal would extend this by replacing the tags with additional JSON, > despite the issues you've described with that format. Since none of those > issues arise when parsing tag=value signatures, I'd like to understand what > motivates the change. > > > Best, > Mauro > > >> On 21 Sep 2026, at 1:43 pm, Timo Gerke <[email protected]> wrote: >> >> Hi Mauro, >> hi all, >> >> sorry, for the delay. My own project needed some attention. >> >> serde_json (or similar to it) may have a strict duplicate name >> handling, but not all parsers have it. >> >> In a heterogeneous infrastructure consisting of older C-ibraries, >> Go webhooks, and proprietary middleboxes, duplicate name handling >> is explicitly undefined according to RFC 8259, Section 4. This >> creates parser differentials where an upstream gateway evaluates >> one key and a downstream consumer reads another, opening a direct >> vector for gateway-bypass attacks. >> >> To guarantee language-agnostic determinism, validation security >> must be enforced by the protocol design through a flattened array >> structure with linear O(n) evaluation, where any anomaly triggers >> an immediate PERMFAIL. >> >> Let Rust handle O(n**m) with n greater than 1 and m equals n+1. >> q.e.d. >> >> Regards, >> Timo >> >> >> It looks like Mauro De Gennaro aimed to say: >>> Hi Timo, >>> >>> Then I am not sure I follow the proposal. Your argument has been that JSON >>> is a hazard in high throughput environments, yet the fields you are >>> describing are already plain tag=value in -06 and never reach a JSON >>> parser. Moving them into JSON would add a base64 decode and a parse to data >>> that currently needs neither, which seems to work against the goal. >>> >>> >>> Best, >>> Mauro >>> >>> >>>>> On 16 Sep 2026, at 18:44, Timo Gerke <[email protected]> wrote: >>>> >>>> Ciao Mauro, >>>> Hi all, >>>> >>>> Sorry, Mauro, I was talking about Revision 06 all the time. >>>> >>>> Regards, >>>> Timo >>>> >>>> It looks like Mauro De Gennaro aimed to say: >>>>> Hi Timo, >>>>> >>>>> I think I have found the source of the misunderstanding, all this time I >>>>> thought you were talking about flattening the JSON recipes but you might >>>>> be referring to an expired pre-adoption draft? >>>>> >>>>> The JSON objects holding selector, algorithm and signature value are from >>>>> draft-clayton-dkim2-spec, the individual submission that preceded the >>>>> working group document. Version -07 of that draft mapped various fields >>>>> of Message-Instance and DKIM2-Signature into JSON, but the draft expired >>>>> on 3 September. The WG document reversed that in its -00, whose changelog >>>>> records removing JSON for hashes, signatures and SMTP parameters. >>>>> >>>>> In draft-ietf-dkim-dkim2-spec-06, section 8.9, the s= tag is a comma >>>>> separated list of selector:algorithm:signature triples in plain ABNF. No >>>>> JSON, no base64 wrapping of a structure, no parser beyond the tag >>>>> scanner. Section 2 limits JSON to the Recipes in r= and nothing else. I >>>>> mention this because clayton-08's signature JSON was in fact an array of >>>>> positional three element arrays, so the design you are arguing against >>>>> was already the one without named keys, and your proposal would move >>>>> toward named objects rather than away from them. >>>>> >>>>> About the capability itself, -06 already supports what I think you may be >>>>> after. Section 8.9 permits more than one signature at a single hop using >>>>> different algorithms, plus one additional signature with the same >>>>> algorithm and a different key length provided a different Selector is >>>>> used. Both signatures sit in one DKIM2-Signature header field, sharing >>>>> one i= and one d=, so there is no extra hop and no distortion of the >>>>> Chain of Custody. Hybrid signing, classical alongside post-quantum, is >>>>> expressible today without any JSON. >>>>> >>>>> >>>>> >>>>> Best, >>>>> Mauro >>>>> >>>>> >>>>>> On 16 Sep 2026, at 16:05, Timo Gerke <[email protected]> wrote: >>>>>> >>>>>> Ciao Mauro, >>>>>> Hi all, >>>>>> >>>>>> It seems there was some misunderstanding. I am not proposing an >>>>>> array of positional tuples, nor an array of objects with deep >>>>>> nested structures. >>>>>> >>>>>> I am proposing a flattened JSON array containing flat, >>>>>> single-level JSON objects representing distinct crypto contexts: >>>>>> >>>>>> [ >>>>>> {"tag1": "value1", "tag2": "value2"}, >>>>>> {"tag3": "value3", "tag4": "value4"} >>>>>> ] >>>>>> >>>>>> The less room for interpretation the spec has, the fewer faulty >>>>>> implementations will exist. >>>>>> >>>>>> With a flattened array of flat objects, the expected structural >>>>>> nesting depth is strictly capped at level 2. A high-throughput >>>>>> gateway under a real productive load can reject non-conforming >>>>>> deeper structures at wire speed immediately upon inspecting the >>>>>> token stream, preventing any deep allocation vectors and >>>>>> eliminating undefined multi-parser anomalies (RFC 8259) by >>>>>> design. >>>>>> >>>>>> Best regards, >>>>>> Timo >>>>>> >>>>>> It looks like Mauro De Gennaro aimed to say: >>>>>>> Hi Timo, >>>>>>> >>>>>>> Both of your arguments hold only if implementers write a custom >>>>>>> streaming parser against your schema. Neither holds for a standard JSON >>>>>>> library, and I think that is the issue. >>>>>>> >>>>>>> Regarding hash map allocation, an array of objects is still an array of >>>>>>> objects. serde_json, Jackson, encoding/json and Python's json will >>>>>>> allocate a map or dict per element, because each element has named >>>>>>> fields. Under any off the shelf parser your design performs more hash >>>>>>> map insertion than the schema you are proposing to replace, which >>>>>>> inverts the argument. Zero hash map allocation would require an array >>>>>>> of positional arrays rather than objects, and at that point the >>>>>>> self-describing property of JSON is gone. >>>>>>> >>>>>>> Also, I did some research, and the hash flooding vector is largely >>>>>>> historical for maintained libraries. Randomized hash seeding is >>>>>>> available in Python, Ruby, Rust and the JVM ecosystem following the >>>>>>> 2011/2012 disclosures, and Jackson ships input constraints by default. >>>>>>> A gateway running a parser with deterministic unseeded hashing has a >>>>>>> dependency problem, not a schema problem. >>>>>>> >>>>>>> Regarding nesting, strictly limits nesting to level 1 describes what >>>>>>> conforming senders emit. It says nothing about what arrives. As I >>>>>>> mentioned in my previous email, a standard parser handed 10,000 nested >>>>>>> braces will recurse into them regardless of what the schema permits, >>>>>>> because the attacker is not reading the schema. The immediate drop you >>>>>>> want comes from a depth limit configured at the parser, and that limit >>>>>>> works identically against a nested schema. >>>>>>> >>>>>>> If implementers use standard libraries, your array allocates more hash >>>>>>> maps and handles recursion no differently, so it is worse on your own >>>>>>> criterion. If implementers write custom streaming parsers for wire >>>>>>> speed drops, they can enforce a depth cap against the current schema >>>>>>> just as easily, so the array gains nothing. Schema shape does not >>>>>>> determine parser architecture, and the defence has to sit at the parser >>>>>>> either way. >>>>>>> >>>>>>> Separately, have you benchmarked any of this, or tested these vectors >>>>>>> against actual JSON libraries? Taking Rust as the example, neither >>>>>>> point survives contact with serde_json. Deserializing into a typed >>>>>>> struct allocates no hash map whatever the shape of the document, >>>>>>> because serde resolves field names through code generated at compile >>>>>>> time rather than through a runtime map, so hash flooding has nothing to >>>>>>> attack. And the recursion limit is not an optional hardening step, it >>>>>>> is the default, capped at 128 levels unless an implementer explicitly >>>>>>> disables it. A hostile document is rejected during the parse, at wire >>>>>>> speed, without any change to the schema. I would be glad to look at >>>>>>> numbers if you have them, but the claims as stated do not describe how >>>>>>> the mainstream parsers actually behave. >>>>>>> >>>>>>> >>>>>>> Best, >>>>>>> Mauro >>>>>>> >>>>>>> >>>>>>>> On 16 Sep 2026, at 14:41, Timo Gerke <[email protected]> wrote: >>>>>>>> >>>>>>>> Ciao Mauro, >>>>>>>> Hi all, >>>>>>>> >>>>>>>> As I already wrote, flat JSON arrays provide a massive advantage >>>>>>>> to CRITIS environments: predictable parsing time. >>>>>>>> >>>>>>>> 1. Nesting: Deeply nested objects force standard parsers into >>>>>>>> recursive allocation. This is crucial with a real load in >>>>>>>> productive, possibly CRITIS environments, provoking >>>>>>>> unpredictable errors under a DDoS attack. A flattened >>>>>>>> array strictly limits nesting to level 1 at the structural >>>>>>>> layer, allowing immediate wire-speed drops. >>>>>>>> >>>>>>>> 2. Hash Flooding: Standard parsers allocate internal hash maps to >>>>>>>> resolve name/value pairs, making them vulnerable to engineered >>>>>>>> collision attacks. A flattened JSON array requires zero hash >>>>>>>> map allocation. It is processed as a pure linear stream. >>>>>>>> Algorithmic key-flooding becomes structure. >>>>>>>> >>>>>>>> Best regards, >>>>>>>> Timo >>>>>>>> >>>>>>>> >>>>>>>> It looks like Mauro De Gennaro aimed to say: >>>>>>>>> Hi Timo, >>>>>>>>> >>>>>>>>>> A flattened JSON array forces strict sequential determinism. >>>>>>>>>> It ensures that duplicate context tags cannot overwrite each >>>>>>>>>> other or create ambiguous parsing paths. >>>>>>>>>> >>>>>>>>>> Regarding predictable parsing time: Sterile lab setups do not >>>>>>>>>> simulate a CRITIS gateway under a DDoS attack. Deeply nested JSON >>>>>>>>>> opens the door to algorithmic complexity exploits. An array >>>>>>>>>> guarantees linear O(n) parsing time at wire speed. >>>>>>>>>> >>>>>>>>>> My idea of a flat array reduces the attack surface to the >>>>>>>>>> smallest possible level. It provides security by design, rather >>>>>>>>>> than security by policy. >>>>>>>>> >>>>>>>>> On flattening as a DoS mitigation: changing the schema does not >>>>>>>>> change what arrives on the wire. An attacker sending a hostile value >>>>>>>>> is not emitting schema-conformant JSON. They will send 10,000 levels >>>>>>>>> of nesting whether the spec describes nested objects or a flat array. >>>>>>>>> A verifier therefore has to bound depth and input length at the >>>>>>>>> parser under either design, and since the mitigation is identical >>>>>>>>> either way, flattening buys no additional resistance. >>>>>>>>> >>>>>>>>> Regarding linear time, a conforming JSON parser makes a single pass >>>>>>>>> and consumes each token exactly once, regardless of shape. Nesting >>>>>>>>> depth determines how much parser stack is live at a given moment, not >>>>>>>>> how many times any byte is examined. Nested JSON is already O(n) in >>>>>>>>> input length, so the guarantee you want from the array is one the >>>>>>>>> current design has. JSON also cannot express the expansion attacks >>>>>>>>> that motivate this worry in other formats, because it has no entity >>>>>>>>> or anchor references; output size is bounded by input size. >>>>>>>>> Also, about algorithmic complexity attacks specifically, in JSON >>>>>>>>> these are normally hash flooding, many colliding keys within a single >>>>>>>>> object degrading insertion. That depends on key count per object, not >>>>>>>>> on depth, so flattening does not mitigate it. >>>>>>>>> >>>>>>>>> >>>>>>>>> Best, >>>>>>>>> Mauro >>>>>>>>> >>>>>>>>> >>>>>>>>> >> >> -- >> >> Timo Gerke >> Hamburg, Germany >> >> "Errare humanum est, sed in errore perservare diabolicum est." >> -- Seneca Rhetor >> <OpenPGP_0x9F03DF9F597BF31E.asc> >> _______________________________________________ >> Ietf-dkim mailing list -- [email protected] >> To unsubscribe send an email to [email protected] > _______________________________________________ > Ietf-dkim mailing list -- [email protected] > To unsubscribe send an email to [email protected] Timo Gerke Hamburg, Germany "If you think technology can solve your security problems then you don't understand the problems and you don't understand the technology." -- Bruce Schneier
OpenPGP_0x9F03DF9F597BF31E.asc
Description: OpenPGP public key
OpenPGP_signature.asc
Description: OpenPGP digital signature
_______________________________________________ Ietf-dkim mailing list -- [email protected] To unsubscribe send an email to [email protected]
