cfn-nag

cfn-nag looks for security problems in AWS CloudFormation templates — security groups open to the world, IAM policies with wildcard actions or resources, unencrypted queues and buckets, rules without descriptions.

It pairs naturally with cfn-lint, which checks the same templates for correctness rather than security, and the two rule sets do not overlap: a template can be perfectly valid and still fail every cfn-nag rule.

Field mapping

cfn-nagDefectDojo
violations[].messagetitle
violations[].id (e.g. F38, W48)vuln_id_from_tool
violations[].type (FAIL / WARN)severity (High / Medium)
violations[].logical_resource_ids[i]component_name
violations[].line_numbers[i]line
filenamefile_path
name, element_types, sibling resourcesdescription

The message is the rule’s own wording and is identical for every resource the rule fires on, which makes it a stable title; the resource is what distinguishes one finding from the next.

A FAIL is a rule the template breaks. A WARN may or may not be a problem depending on intent — W2, “cidr open to world on ingress”, is legitimate on a load balancer and not on an instance — so the two are not flattened to one severity. cfn-nag reports no CWE.

One finding per resource, not per violation

A single cfn-nag violation can cover several resources. The unencrypted-queue rule W48 fires once for a template with two unencrypted queues, reporting parallel logical_resource_ids and line_numbers lists rather than two violations.

The parser pairs those lists by index and emits one finding per resource, because a violation-level finding could not be closed by fixing one of the two queues. The many_vuln fixture has nine violations and yields ten findings for exactly this reason. Each finding names its siblings in the description so a reader knows the rule fired elsewhere too.

Sample Scan Data

Sample cfn-nag files are available at unittests/scans/cfn_nag.

Generating an importable file

cfn-nag is a Ruby gem, and cfn_nag_scan takes a directory, not a file:

gem install cfn-nag
cfn_nag_scan --input-path ./templates --output-format json > cfn-nag.json

filename in the report is whatever path cfn-nag was given, so scanning . yields ./template.yaml; the parser drops that leading ./ and rewrites nothing else. Scan with a relative path if you want portable paths in DefectDojo.

cfn-nag exits non-zero when it finds anything, so a CI step that fails the build on a non-zero exit will stop before the report is uploaded.

The fixtures committed with this parser were produced with cfn-nag 0.8.10 by three separate runs, each against a directory containing one of the templates committed alongside them in unittests/scans/cfn_nag/:

FixtureFindings
cfn_nag_no_vuln.json0 — clean.yaml, an encrypted queue
cfn_nag_one_vuln.json1 — single.yaml, one unencrypted queue
cfn_nag_many_vuln.json10 from 9 violations — many.yaml: an open security group, a wildcard IAM policy, two unencrypted queues

Default deduplication hashcode fields

title, cwe, line, file_path, description — the legacy default. The description carries the resource name, which is what keeps two findings of one rule distinct.