feat(hdf-converters): add KICS JSON to HDF mapper - #8573
Conversation
852e4a7 to
92554a4
Compare
Maps the native `kics scan --report-formats json` format, plus its fingerprint, frontend intake wiring, sample data and spec. KICS also emits SARIF, and unusually its SARIF is well formed — in a real scan 72 of 72 rules carried a proper CWE taxonomy relationship. What SARIF drops is everything about remediation and identity: - `expected_value`, on 100% of findings. The SARIF message keeps only `actual_value`, so a control can state what the configuration is but never what it should be. - `issue_type` — MissingAttribute 767 / IncorrectValue 68 / RedundantAttribute 14 in the scan measured. Add-a-block versus fix-a-value. - `similarity_id`, KICS's own stable finding fingerprint. - `resource_name`, `search_value`, `description_id`. - One level of severity granularity: CRITICAL and HIGH both become `error`. One control per query, each occurrence a result. KICS already groups its output as `queries[].files[]`, so it maps directly. No severity maps to impact 0. Impact 0.0 reports Not Applicable in HDF and would drop the finding from the compliance score rather than rating it low; INFO and TRACE map to 0.1. Scan coverage ------------- KICS reports violations only. Its output carries no record of the queries that ran without finding anything — `queries` holds only those that fired — so no passing control can be derived from it and a converted profile is failures-only by construction. On a real scan that means 72 of 2,034 executed queries appear, and the profile renders as 100% failed. A `kics-scan-coverage` control carries the denominator: queries executed, queries with findings, files scanned and parsed, with a description stating plainly that the compliance ratio should not be read as a pass rate. Impact 0 reports Not Applicable, so the record cannot skew the ratio it exists to explain. Control resolution ------------------ Follows the pattern the Checkov and AWS Config mappers already use: a reviewed per-rule table is the authoritative source, shipped as data, rather than a mapping computed at conversion time. That is what lets those tables carry control enhancements — CheckovToCciAndNistMappingData resolves CKV2_ADO_1 to CM-3(2) and CM-5(1), a precision the CWE table structurally cannot express. Resolution order, with the tier that answered recorded in a `nistMapping` tag: KicsToCciAndNistMappingData[query_id] -> mapped CWE lookup -> cwe-derived static-analysis defaults -> static-fallback KICS ships its full query catalog as data — 1,811 metadata.json files in the distributed image — so every query is known ahead of a scan and the table can be built completely rather than discovered from whatever a scan happens to trip. The table ships empty. Candidate mappings are ranked against the 800-53 Rev 5 catalog and await adjudication; shipping unreviewed rows would defeat the point of a reviewed table. The resolver takes the table as a parameter so all three tiers are tested without shipping unreviewed data. See mitre/hdf-libs#239. Until the table fills, KICS resolves through its CWE, which reaches only 52% of queries by volume — hence the marker, so the remainder is visibly a fallback rather than a mapping. The source CWE is retained in tags even when it does not resolve. The fingerprint keys on `kics_version` and `severity_counters` alongside `queries`; verified against all 134 sample files in sample_jsons with no collision in either direction. Sample data is generated from a small synthetic Terraform tree, so it is reproducible and carries no proprietary input. Signed-off-by: clem-field <kc8yhe@me.com>
92554a4 to
a090d02
Compare
|
Added: a scan coverage recordFollowing review feedback that a KICS profile reads as 100% failed. KICS reports violations only. Its output has no record of the queries that ran The converter now emits a with a description stating plainly that KICS does not enumerate passing queries This is deliberately a record, not synthesised passes. KICS tells us how many |




Closes #8572.
Maps the native
kics scan --report-formats jsonformat, plus its fingerprint, frontend intake wiring, sample data and spec.Why not sarif2hdf
KICS emits SARIF, and unusually its SARIF is well formed — in a real scan, 72 of 72 rules carried a proper CWE taxonomy relationship. That is better than most scanners manage.
What SARIF drops is everything about remediation and identity:
expected_valueactual_value, so a control can state what the configuration is but never what it should beissue_typesimilarity_idresource_name,search_value,description_iderrorDesign notes
One control per query, each occurrence a result. KICS already groups its output as
queries[].files[], so it maps directly.No severity maps to impact 0.
impact 0.0reports Not Applicable in HDF and would drop the finding from the compliance score rather than rating it low; INFO and TRACE map to 0.1.Fingerprint keys on
kics_versionandseverity_countersalongsidequeries, verified against all 134 sample files insample_jsonswith no collision in either direction.NIST mapping provenance — worth a look
Controls carry a
nistMappingtag readingcwe-derivedorstatic-fallback, so a resolved mapping stays distinguishable from a static default.The motivation is measurable. KICS carries a CWE on all 1,811 of its shipped queries across 102 distinct CWEs, but only 30 of those resolve against
CweNistMappingData— 52% of queries by volume. The largest misses are the most-used checks: CWE-778 (211 queries), CWE-665 (113), CWE-710 (111), CWE-668 (78).Without the marker, roughly half of a KICS run carries
SA-11, RA-5with nothing to indicate it is a fallback rather than a mapping. The source CWE is retained in tags even when it does not resolve, so the gap is visible rather than silent.Thirteen mappers in this repo resolve
tags.nistthrough the same table, so this is likely a broader condition than KICS. Raising it here rather than expanding scope; happy to drop the tag if maintainers would rather not set the precedent in a converter PR.The equivalent converter for the v3 line is mitre/hdf-libs#240, and mitre/hdf-libs#239 tracks the mapping work this anticipates.
Fixtures
Generated from a small synthetic Terraform tree, so they are reproducible and carry no proprietary input: findings across four severities, and a genuine zero-findings scan.
Testing
13 tests covering rule grouping, the severity scale, the provenance marker, retention of unresolved CWEs, the remediation pair, and the zero-findings case.
vitest runinlibs/hdf-converters: 4 failures, all reproducing identically on an unmodifiedmastercheckout (3 sonarqube tests that reach a live API, 1 splunk reverse mapper).