mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-09-28 06:45:17 +08:00
The r3 fold scoped only the dmarc verdict to its clause. SPF and DKIM still came from a whole-string, last-match-wins regex scan, so the same quoted/comment smuggle closed for dmarc still authenticated a spoofed From (GHSA-rxqh-5572-8m77), e.g. spf=fail smtp.mailfrom="x spf=pass smtp.mailfrom=example.com "@evil.test spf=fail (spf=pass) smtp.mailfrom=a@example.com spf=fail smtp.mailfrom=a.spf=pass@example.com dkim=pass header.d=evil.test header.i="x header.d=example.com y"@evil.test Every verdict now comes from the leading method=result token of its own clause (from _ar_clauses, comments dropped), and its domains only from that clause. Properties are read by a token scanner that consumes quoted-strings and other key=value tokens whole, so quoted contents are never read as properties while a quoted value still is (header.from="example.com"). SPF fails closed on more than one spf clause; DKIM accepts any single dkim=pass clause whose own header.d aligns (multi-signature mail is normal), never mixing clauses. The whole-string methods/props (methods["dmarc"] was dead) are gone. Also: a stray ')' at depth 0 is now unbalanced (it split header.from out of the dmarc clause); a From with more than 64 '(' takes the silent empty-sender drop instead of a parseaddr RecursionError logged as an error; the cap test asserts the cap directly instead of wall-clock timing; the empty-From drop assertion moves next to the other _extract_email_address rejects; and the untested >1-dmarc, unbalanced and backslash-escape rules get reject strings.