Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
cfn_nag — Linting tool for CloudFormation templates | Kitploit
Tools/GitHubGitHub/stelligent/cfn_nag
Static Code Analysis (SAST)Configuration AuditingCloud SecurityDevSecOpsSecret DetectionMisconfigurationTop in Configuration Auditing #20Top in Misconfiguration #20
GitHubstelligent/cfn_nag
1.3k208454 years agoReviewed by Kitploit

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

cfn_nag

Linting tool for CloudFormation templates

View Repository

cfn_nag

Background

The cfn-nag tool looks for patterns in CloudFormation templates that may indicate insecure infrastructure. Roughly speaking, it will look for:

  • IAM rules that are too permissive (wildcards)
  • Security group rules that are too permissive (wildcards)
  • Access logs that aren't enabled
  • Encryption that isn't enabled
  • Password literals

For more background on the tool, please see this post at Stelligent's blog:

Finding Security Problems Early in the Development Process of a CloudFormation Template with "cfn-nag"

Installation

Gem Install

Presuming Ruby >= 2.5.x is installed, installation is just a matter of:

gem install cfn-nag

Brew Install

On MacOS or Linux you can alternatively install with brew:

brew install ruby brew-gem
brew gem install cfn-nag

CodePipeline

To run cfn_nag as an action in CodePipeline, you can deploy via the AWS Serverless Application Repository.

Usage

To execute:

cfn_nag_scan --input-path <path to cloudformation json>

The path can be a directory or a particular template. If it is a directory, all .json, .template, .yml and .yaml files will be processed, including recursing into subdirectories.

The default output format is free-form text, but json output can be selected with the --output-format json flag.

Optionally, a --debug flag will dump information about the internals of rule loading.

Run with --help for a full listing of supported switches.

To see a list of all the rules cfn-nag currently supports, there is a command-line utility that will dump them to stdout:

cfn_nag_rules

Results

  • The results are dumped to stdout
  • A failing violation will return a non-zero exit code.
  • A warning will return a zero/success exit code.
  • A fatal violation stops analysis (per file) because the template is malformed in some severe way

Running in Docker

A Dockerfile is provided for convenience. It is published on DockerHub as stelligent/cfn_nag.

https://hub.docker.com/r/stelligent/cfn_nag

You can also build it locally.

docker build -t stelligent/cfn_nag .

You can mount a local directory containing templates into the Docker container and then call cfn_nag in the container. This example uses the test templates used in unit testing cfn_nag:

$ docker run -v `pwd`/spec/test_templates:/templates -t stelligent/cfn_nag /templates/json/efs/filesystem_with_encryption.json
{
  "failure_count": 0,
  "violations": [

  ]
}
$ docker run -v `pwd`/spec/test_templates:/templates -t stelligent/cfn_nag /templates/json/efs/filesystem_with_no_encryption.json
{
  "failure_count": 1,
  "violations": [
    {
      "id": "F27",
      "type": "FAIL",
      "message": "EFS FileSystem should have encryption enabled",
      "logical_resource_ids": [
        "filesystem"
      ]
    }
  ]
}

Running as a GitHub Action

cfn_nag_scan can be run as part of a GitHub Workflow to evaluate code during continuous integration pipelines.

In your GitHub Workflow file, create a step which uses the cfn_nag Action:

- name: Simple test
  uses: stelligent/cfn_nag@master
  with:
    input_path: tests

More information about the GitHub Action can be found here.

Results Filtering

Profiles

cfn-nag supports the notion of a "profile" which is effectively an allow list of rules to apply. The profile is a text file that must contain a rule identifier per line. When specified via the --profile-path command line argument, cfn-nag will ONLY return violations from those particular rules.

The motivation behind creating a "profile" is that different developers might care about different rules. For example, an "infrastructure_developer" might care about IAM rules, while an "app_developer" might not even be able to create IAM resources and therefore not care about those rules.

Here is an example profile:

F1
F2
F27
W3
W5

Global Deny List

The deny list is basically the opposite of the profile: it's a list of rules to NEVER apply. When specified via the --deny-list-path command line argument, cfn-nag will NEVER return violations from those particular rules specified in the file.

In case a rule is specified in both, the deny list will take priority over the profile, and the rule will not be applied.

The format is as follows. The only two salient fields are RulesToSuppress and the id per item. The reason won't be interpreted by cfn-nag, but it is recommended to justify and document why the rule should never be applied.

RulesToSuppress:
- id: W3
  reason: W3 is something we never care about at enterprise X

Per-Resource Rule Suppression

In the event that there is a rule that you want to suppress, a cfn_nag Metadata key can be added to the affected resource to tell cfn_nag to not raise a failure or warning for that rule.

For example, if you are setting up a public-facing ELB that's open to inbound connections from the internet with resources like the following:

public_alb.yaml

# Partial template
PublicAlbSecurityGroup:
  Properties:
    GroupDescription: 'Security group for a public Application Load Balancer'
    VpcId:
      Ref: vpc
  Type: AWS::EC2::SecurityGroup
PublicAlbSecurityGroupHttpIngress:
  Properties:
    CidrIp: 0.0.0.0/0
    FromPort: 80
    GroupId:
      Ref: PublicAlbSecurityGroup
    IpProtocol: tcp
    ToPort: 80
  Type: AWS::EC2::SecurityGroupIngress

cfn_nag will raise warnings like the following:

$ cfn_nag_scan -i public_alb.yaml
------------------------------------------------------------
public_alb.yaml
------------------------------------------------------------------------------------------------------------------------
| WARN W9
|
| Resources: ["PublicAlbSecurityGroup"]
|
| Security Groups found with ingress cidr that is not /32
------------------------------------------------------------
| WARN W2
|
| Resources: ["PublicAlbSecurityGroup"]
|
| Security Groups found with cidr open to world on ingress.  This should never be true on instance.  Permissible on ELB

Failures count: 0
Warnings count: 2

By adding the metadata, these warnings can be suppressed:

public_alb_with_suppression.yaml

# Partial template
PublicAlbSecurityGroup:
  Properties:
    GroupDescription: 'Security group for a public Application Load Balancer'
    VpcId:
      Ref: vpc
  Type: AWS::EC2::SecurityGroup
  Metadata:
    cfn_nag:
      rules_to_suppress:
        - id: W9
          reason: "This is a public facing ELB and ingress from the internet should be permitted."
        - id: W2
          reason: "This is a public facing ELB and ingress from the internet should be permitted."
PublicAlbSecurityGroupHttpIngress:
  Properties:
    CidrIp: 0.0.0.0/0
    FromPort: 80
    GroupId:
      Ref: PublicAlbSecurityGroup
    IpProtocol: tcp
    ToPort: 80
  Type: AWS::EC2::SecurityGroupIngress
$ cfn_nag_scan -i public_alb_with_suppression.yaml
------------------------------------------------------------
public_alb_with_supression.yaml
------------------------------------------------------------
Failures count: 0
Warnings count: 0

Setting Template Parameter Values

Download Tool