From ca6503f5a802bf6335fc7c601de573129bc2d1e7 Mon Sep 17 00:00:00 2001 From: Ricardo Valdes Date: Wed, 16 Sep 2026 20:34:47 -0400 Subject: [PATCH] fix: align JSON Input filter and rule contracts --- filters/audits/json-input.md | 40 +++++++++++++++++ .../testdata/filter-contracts/json-input.json | 43 +++++++++++++++++++ .../json-input/json_injection_attempts.yml | 2 +- 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 filters/audits/json-input.md create mode 100644 plugins/alerts/testdata/filter-contracts/json-input.json diff --git a/filters/audits/json-input.md b/filters/audits/json-input.md new file mode 100644 index 000000000..e974b367c --- /dev/null +++ b/filters/audits/json-input.md @@ -0,0 +1,40 @@ +# JSON Input normalization and rule review + +Correct the injection rule target.host grouping name to the SDK schema. + +This draft targets UTMStack `v11`. It contains 0 filter changes +and 1 rule changes for this technology only. Review covered +1 filter configurations and 10 matching shipped rule files. +Unchanged rules are listed in the regression manifest; they are not duplicated in the diff. + +## Contract and validation + +- Compared exact standard names/types with go-sdk v1.1.31 and the supplied UTMStack dictionaries. +- Checked documented pipeline ordering, rename/move behavior, open vendor log fields, + event-side versus alert-side fields, and surviving fields used by affected rule predicates/history/grouping. +- Strict SDK configuration decoding and actual CEL compilation pass for this scope. +- 1 synthetic normalization cases pass, including SDK Event conversion and any + trigger predicate assertions recorded in the manifest. +- The scoped alerts module tests and `git diff --check` pass with the shared contract runner applied. + +The shared alert-contract PR supplies the reusable Go runner for the manifest in +`plugins/alerts/testdata/filter-contracts/json-input.json`. Apply that support before running `go test ./...` in `plugins/alerts`. + +The model starts from synthetic extraction results. It does not run complex grok, +JSON/KV/XML/CSV extraction, time conversion, dynamic plugins, historical OpenSearch +queries, or the closed EventProcessor. Raw vendor logs and resulting alerts must +still be checked in staging before rollout. No customer false-positive reduction +has been measured and no production rollout is included. + +The generic JSON parser places payload fields under log. This change only corrects an invalid target.hostname grouping path. The fixture explicitly supplies standard side identity; deployments still need upstream/custom normalization to supply origin.ip for this rule to trigger. This PR does not claim that arbitrary JSON automatically gains standard side fields. + +## References + +- [SDK schema](https://github.com/threatwinds/go-sdk/blob/v1.1.31/plugins/plugins.proto) +- [Filter steps](https://github.com/threatwinds/go-sdk/wiki/Filter-Steps-Reference) +- [Standard event schema](https://github.com/threatwinds/go-sdk/wiki/Standard-Event-Schema) +- [Rule implementation](https://github.com/threatwinds/go-sdk/wiki/Implementing-Rules) + +`afterEvents`, empty noncapturing grok names, supported numeric strings, and custom +`log.*` fields are accepted. Existing textual protocol casing and vendor action names +are preserved unless a concrete consumer mismatch requires correction. diff --git a/plugins/alerts/testdata/filter-contracts/json-input.json b/plugins/alerts/testdata/filter-contracts/json-input.json new file mode 100644 index 000000000..296001b6e --- /dev/null +++ b/plugins/alerts/testdata/filter-contracts/json-input.json @@ -0,0 +1,43 @@ +{ + "technology": "JSON Input", + "filters": [ + "filters/json/json-input.yml" + ], + "rules": [ + "rules/json/json-input/deserialization_attacks.yml", + "rules/json/json-input/graphql_abuse.yml", + "rules/json/json-input/json_hijacking_attempts.yml", + "rules/json/json-input/json_injection_attempts.yml", + "rules/json/json-input/jsonp_vulnerabilities.yml", + "rules/json/json-input/jwt_algorithm_confusion.yml", + "rules/json/json-input/jwt_token_security_issues.yml", + "rules/json/json-input/mass_assignment_attack.yml", + "rules/json/json-input/nosql_injection_json.yml", + "rules/json/json-input/prototype_pollution_attempts.yml" + ], + "fixtures": [ + { + "name": "json_rule_standard_side_fields", + "filter": "json/json-input.yml", + "input": { + "origin": { + "ip": "192.0.2.5" + }, + "target": { + "host": "web-lab" + }, + "log": { + "payload": "" + } + }, + "expected": { + "origin.ip": "192.0.2.5", + "target.host": "web-lab" + }, + "absent": [], + "rules": { + "rules/json/json-input/json_injection_attempts.yml": true + } + } + ] +} diff --git a/rules/json/json-input/json_injection_attempts.yml b/rules/json/json-input/json_injection_attempts.yml index e85aa80eb..5d0ef499d 100644 --- a/rules/json/json-input/json_injection_attempts.yml +++ b/rules/json/json-input/json_injection_attempts.yml @@ -42,4 +42,4 @@ afterEvents: count: 3 groupBy: - adversary.ip - - target.hostname + - target.host