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

Attachment: OpenPGP_0x9F03DF9F597BF31E.asc
Description: OpenPGP public key

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

_______________________________________________
Ietf-dkim mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to