Skip to content

Add a KICS mapper (native JSON, not SARIF) #8572

Description

@clem-field

Summary

There is no KICS converter in hdf-libs, heimdall2 or the SAF CLI today. KICS
(Checkmarx, Apache-2.0) is a widely used IaC scanner covering Terraform,
CloudFormation, ARM, Kubernetes, Ansible, Docker, CI/CD definitions and more —
1,811 queries in the current image.

KICS emits SARIF, so sarif2hdf is a partial path. It is a lossy one, and the
native JSON carries materially more.

Measured fidelity gap

Scanned a real Terraform tree with checkmarx/kics:latest, emitting JSON and
SARIF from the same run: 849 findings across 72 queries.

What SARIF preserves — and this is better than most scanners manage — is the CWE
taxonomy: 72 of 72 rules carry a proper relationships[].target against a
CWE toolComponent. Rule name, description, helpUri and riskScore also
survive.

What SARIF drops:

Native field Fate in SARIF Why it matters
expected_value dropped on all 849 findings the message keeps only actual_value, so you get what it is and never what it should be
issue_type dropped MissingAttribute 767 / IncorrectValue 68 / RedundantAttribute 14 — add-a-block versus fix-a-value
similarity_id dropped KICS's own stable finding fingerprint, the natural cross-run dedup key
resource_name, search_value, description_id dropped
severity coarsened 5 → 4 CRITICAL and HIGH both collapse to error

resource_type survives only as prose inside the message string, not as a
structured field, so it cannot be filtered on.

Why this is a cheap converter to build

Unlike most scanners, KICS ships its own catalog as data: 1,811
metadata.json files under /app/bin/assets/queries/, each with id,
queryName, severity, category, descriptionText, descriptionUrl,
platform, cloudProvider, cwe and riskScore, with the rule's query.rego
beside it. Nothing has to be reverse-engineered or synthesized to produce
profile-grade output.

Every query carries a cwe, so tags.nist resolves through the existing CWE
mapping with no new mapping table.

Proposed mapping

HDF field Source
control / requirement id query_id (stable UUID)
title query_name
desc description
impact severity, five levels — see note below
tags.nist / tags.cci derived from cwe
tags platform, cloud_provider, category, risk_score, issue_type, resource_type
refs query_url
code_desc file_name, line, resource_type, search_key
results[].message expected_value vs actual_value — the remediation pair
passthrough scan counters, files_scanned, queries_total, kics_version

Granularity: one control per query, with each occurrence a result. KICS already
groups its output that way — queries[].files[] — so it maps directly.

Gotchas found while measuring

  • oldSeverity appears alongside severity in the catalog; KICS is migrating
    its scale. A converter must read severity and ignore oldSeverity, or
    findings silently downgrade.
  • Five native severities (CRITICAL/HIGH/MEDIUM/LOW/INFO) need five
    impact values. Mapping INFO to 0.0 would report Not Applicable and drop
    those findings from the compliance score.
  • The same query id appears across platforms with different platform and
    cloud_provider; resolution should not assume query_id alone is unique per
    scan context.

Fixtures

Reproducible from a small synthetic Terraform tree — no proprietary input
required. Happy to contribute the converter along with fixtures covering
findings across severities, a scan reporting parse failures, and the
zero-findings case.

Scope in this repo

libs/hdf-converters/src/kics-mapper.ts built on BaseConverter, exported from
index.ts, INPUT_TYPES.KICS plus fingerprint entry in
src/utils/fingerprinting.ts, a case in apps/frontend/src/store/report_intake.ts,
sample data under sample_jsons/kics_mapper/, a spec, and a line in the
supported-formats README list.

Detection note: KICS JSON is distinctive — queries, severity_counters,
scan_id, kics_version — so the fingerprint can key on names no other
converter uses, rather than the generic results/version pair.

Related: mitre/hdf-libs#238 tracks the same converter for the v3 line.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions