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]

Reply via email to