mirror of
https://github.com/domainaware/parsedmarc.git
synced 2026-09-12 08:57:59 +00:00
Store numbers as number_value; fix conditional guards to != ""
Two corrections confirmed against Google's official content-hub parsers
(content/parsers/third_party/community/*/cbn):
1. Numbers as numbers. count, source_asn, successful_session_count and
failed_session_count were being stored in additional.fields as string_value.
Store them as number_value instead (build string -> convert to uinteger ->
rename to number_value, the content-hub idiom), so SecOps can range-query and
sort them, per parsedmarc's "store numbers as numbers" rule. Booleans stay
string_value (content-hub never uses bool_value) and are still converted in
step 1b for the == "true"/"false" comparisons.
2. Conditional guards. Replaced bare `if [field] {` with `if [field] != "" {`
(76 guards + the detection cascade + policy_override). After 1a initializes
every tested field to "", a bare `if` is true for an empty field (Logstash/CBN
semantics), which would misfire detection and emit empty labels. content-hub
uses `!= ""` ~111x vs 2 bare (both flags); parser flags (no_json_payload,
not_json, *_nan) correctly stay bare.
Verified: braces balance, no stray bare field-guards, all if-tested fields
initialized, all four numeric fields emit number_value.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d8b8186328
commit
53402c28fe
@@ -48,17 +48,23 @@ DMARC types.
|
||||
## Caveats
|
||||
|
||||
1. **Unvalidated** — see [Status](#status).
|
||||
2. **JSON type handling** — parsedmarc emits `dmarc_aligned` / `spf_aligned` /
|
||||
`dkim_aligned` / `testing` / `normalized_timespan` as JSON booleans and
|
||||
`count` / `*_session_count` / `source_asn` as numbers. Chronicle's `json{}`
|
||||
filter **preserves the original JSON type**, so the parser explicitly
|
||||
converts these to strings (`mutate { convert => { … => "string" } }`) before
|
||||
any comparison — otherwise `[dmarc_aligned] == "false"` would never match.
|
||||
Relatedly, every field tested in an `if` is initialized to `""` *before* the
|
||||
`json` filter, because CBN raises `_failed_parsing_` on a conditional that
|
||||
references a field absent from the log. A DMARC-fail record
|
||||
(`dmarc_aligned=false`) should yield `security_result.category =
|
||||
AUTH_VIOLATION` — still worth confirming in the validation tool.
|
||||
2. **JSON types** — Chronicle's `json{}` filter **preserves the original JSON
|
||||
type**, so parsedmarc's booleans and numbers are handled differently:
|
||||
- **Booleans** (`dmarc_aligned` / `spf_aligned` / `dkim_aligned` / `testing`
|
||||
/ `normalized_timespan`) are converted to strings so `[dmarc_aligned] ==
|
||||
"false"` works, and stored as `string_value` (Google's content-hub parsers
|
||||
never use `bool_value`).
|
||||
- **Numbers** (`count` / `*_session_count` / `source_asn`) are stored as
|
||||
`number_value` — built as a string, `convert`-ed to `uinteger`, then
|
||||
renamed — so SecOps can range-query and sort them (parsedmarc's "store
|
||||
numbers as numbers" rule).
|
||||
|
||||
Every `if`-tested field is initialized to `""` *before* `json` and guarded
|
||||
with `!= ""`: CBN raises `_failed_parsing_` on a conditional referencing an
|
||||
absent field, and treats an initialized-but-empty field as present. A
|
||||
DMARC-fail record (`dmarc_aligned=false`) should yield
|
||||
`security_result.category = AUTH_VIOLATION` — worth confirming in the
|
||||
validation tool.
|
||||
3. **Aggregate count** — a DMARC aggregate record summarizes `count` messages
|
||||
from one source IP, not a single message. Each record becomes one
|
||||
`EMAIL_TRANSACTION` with `count` carried in `additional.fields`. There is no
|
||||
|
||||
Reference in New Issue
Block a user