From c3bf1d06d60d3a08d9b6c2af78ddbb78db32a7bd Mon Sep 17 00:00:00 2001 From: Greg Anderson Date: Tue, 18 Aug 2026 15:32:45 -0600 Subject: [PATCH] docs(rules-engine-2): document the exploit-evidence, reachability and exposure fields Pairs with the dojo-pro change that adds these to the rule item envelope. Adds the two new field groups to the available-fields contract table, extends the asset block to name its three new keys, and adds a section explaining what each one means -- including the exploit-maturity scale, since "20" is not self-describing, and the distinction between reachability (can the vulnerable code be reached inside the app) and exposure (can the asset be reached from outside), which are separate questions on separate rollups and easy to conflate. Also states why both exposure answers are offered: the manual checkbox is what somebody ticked, the verdict is computed from connector evidence, and they can disagree. And it records that these read empty where the feature populating them is off, so an author knows a rule will match nothing rather than misbehave. English only. The translated variants of this page lag behind by design and are updated in dedicated translation passes -- the acceptance fields added earlier are likewise not yet in them. Co-Authored-By: Claude Opus 5 --- .../rules_engine_2/building_rules.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/content/automation/rules_engine_2/building_rules.md b/docs/content/automation/rules_engine_2/building_rules.md index cc3a1285f6..68c62c08dd 100644 --- a/docs/content/automation/rules_engine_2/building_rules.md +++ b/docs/content/automation/rules_engine_2/building_rules.md @@ -134,13 +134,30 @@ Each item carries a fixed set of Finding fields. This list is a contract, so it | Dates | `date`, `mitigated`, `last_status_update`, `sla_expiration_date` | | Location | `file_path`, `line`, `component_name`, `component_version`, `service` | | Classification | `cwe`, `vulnerability_ids`, `tags` | +| Exploit evidence | `exploit_maturity`, `kev_due_date`, `vex_state` | +| Reachability | `reachability`, `reachability_confidence` | -Alongside `finding`, each item carries `test` (`id`, `title`, `scan_type`), `engagement` (`id`, `name`), `product` (`id`, `name`), `product_type` (`id`, `name`), and `ctx`. +Alongside `finding`, each item carries `test` (`id`, `title`, `scan_type`), `engagement` (`id`, `name`), `product` (`id`, `name`, `internet_accessible`, `business_criticality`, `exposure`), `product_type` (`id`, `name`), and `ctx`. Dates are ISO-8601 strings. That is deliberate: it means `gt` and `lt` order them correctly as text, so `2026-07-28` is correctly greater than `2026-01-01`. `priority`, `risk` and `risk_score` come from Pro's prioritization. A Finding that has not been scored yet carries no value for them. +### Conditioning on exploitability and exposure + +Four of the fields above answer "is this actually exploitable, and can it be reached", which is what most remediation-priority rules are really asking. + +- `exploit_maturity` is a number: `0` none, `10` proof of concept, `20` weaponized, `30` observed being exploited in the wild. Greater-than comparisons work the way you would expect, so `exploit_maturity gte 20` means "weaponized or worse". +- `kev_due_date` is CISA's own deadline for a vulnerability in the Known Exploited Vulnerabilities catalog, and is empty for anything not listed. +- `vex_state` is the CycloneDX analysis verdict, when a VEX document has been imported: `exploitable`, `not_affected`, `in_triage`, `false_positive`, `resolved`, `resolved_with_pedigree`. +- `reachability` is whether the vulnerable code can be reached *inside* the application: `reachable_runtime`, `reachable_static`, `potentially_reachable`, `unreachable`, `unknown`. `reachability_confidence` is a number from 0.0 to 1.0. + +Exposure is a separate question, and it lives on the asset rather than the Finding: `product.exposure` is whether the asset can be reached from *outside*, as `exposed_public`, `exposed_limited`, `reachable_private`, `internal_only` or `unknown`. `reachable_private` means an internal path exists but no internet one. + +`product.internet_accessible` is the older manual checkbox on the asset. Both are offered because they can disagree: the checkbox is what somebody ticked, while `exposure` is computed from the evidence connectors collect, and prefers an explicit override when one is set. A rule that means "reachable from the internet" usually wants `exposure`, falling back to the checkbox on an instance with no exposure evidence. + +These fields are populated by Pro's threat intelligence, reachability and asset-exposure features. Where a feature is off, its fields read empty (`reachability` reads `unknown`), so a rule written against them matches nothing rather than matching on half-populated data. + ### Conditions An **If / Filter** node holds a list of condition rows. Each row is a path, an operator, and a value. **Match** decides whether every row has to hold (`all`) or just one of them (`any`).