Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
cfn_nag — CloudFormation 模板的 lint 检查工具 | Kitploit
工具/GitHubGitHub/stelligent/cfn_nag
静态代码分析 (SAST)配置审计云安全DevSecOps秘密检测错误配置配置审计 分类第 20 名错误配置 分类第 20 名
GitHubstelligent/cfn_nag

cfn_nag

1.3k208454年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CloudFormation 模板的 lint 检查工具

查看仓库

cfn_nag

背景

cfn-nag 工具用于查找 CloudFormation 模板中可能表明基础设施不安全的模式。大致来说,它会查找:

  • 过于宽松(通配符)的 IAM 规则
  • 过于宽松(通配符)的安全组规则
  • 未启用的访问日志
  • 未启用的加密
  • 密码字面量

关于该工具的更多背景,请参阅 Stelligent 博客上的这篇文章:

利用 "cfn-nag" 在 CloudFormation 模板开发流程早期发现安全问题

安装

Gem 安装

假设已安装 Ruby >= 2.5.x,安装只需:

gem install cfn-nag

Brew 安装

在 MacOS 或 Linux 上,你也可以选择使用 brew 安装:

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

CodePipeline

要将 cfn_nag 作为 CodePipeline 中的操作运行,可以通过 AWS Serverless Application Repository 进行部署。

用法

执行方式如下:

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

该路径可以是目录或特定的模板。如果是目录,则将处理所有 .json, .template、.yml 和 .yaml 文件,包括递归到子目录中。

默认输出格式是自由格式文本,但也可以通过 --output-format json 标志选择 JSON 输出。

可选地,--debug 标志会转储规则加载的内部信息。

运行 --help 可查看所有受支持开关的完整列表。

要查看 cfn-nag 当前支持的所有规则列表,可以使用一个命令行工具将它们输出到 stdout:

cfn_nag_rules

结果

  • 结果会输出到 stdout
  • 失败的违规将返回非零退出码。
  • 警告将返回零(成功)退出码。
  • 致命违规会停止(按文件)分析,因为模板存在某种严重格式错误。

在 Docker 中运行

为方便起见,提供了一个 Dockerfile。它已作为 stelligent/cfn_nag 发布在 DockerHub 上。

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

你也可以在本地构建它。

docker build -t stelligent/cfn_nag .

你可以将包含模板的本地目录挂载到 Docker 容器中,然后在容器中调用 cfn_nag。此示例使用 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"
      ]
    }
  ]
}

作为 GitHub Action 运行

cfn_nag_scan 可以作为 GitHub Workflow 的一部分运行,在持续集成流水线中评估代码。

在你的 GitHub Workflow 文件中,创建一个使用 cfn_nag Action 的步骤:

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

有关 GitHub Action 的更多信息,请参见此处。

结果过滤

配置文件

cfn-nag 支持 "profile(配置文件)" 的概念,它实际上是一个要应用的规则允许列表。该配置文件是一个文本文件,每行必须包含一个规则标识符。当通过 --profile-path 命令行参数指定时,cfn-nag 将只返回来自这些特定规则的违规。

创建 "profile" 的动机在于,不同的开发者可能关心不同的规则。例如,"infrastructure_developer" 可能关心 IAM 规则,而 "app_developer" 可能甚至无法创建 IAM 资源,因此不关心这些规则。

以下是一个 profile 示例:

F1
F2
F27
W3
W5

全局拒绝列表

拒绝列表基本上与 profile 相反:它是一个从不应用的规则列表。当通过 --deny-list-path 命令行参数指定时,cfn-nag 将永远不会返回文件中指定的那些特定规则的违规。

如果某个规则同时在两者中指定,则拒绝列表优先于 profile,并且该规则不会被应用。

格式如下。唯一两个重要字段是 RulesToSuppress 和每个条目的 id。reason 不会被 cfn-nag 解释,但建议用来说明并记录为什么该规则永远不应被应用。

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

按资源规则抑制

如果有想要抑制的规则,可以在受影响的资源上添加 cfn_nag 的 Metadata 键,告诉 cfn_nag 不要针对该规则引发失败或警告。

例如,如果你正在设置一个面向公众、允许来自互联网的入站连接的 ELB,资源如下所示:

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 将引发如下警告:

$ 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

通过添加 metadata,可以抑制这些警告:

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

设置模板参数值

CloudFormation 模板参数可能会给静态分析带来问题,因为参数值是在部署时指定的。换句话说,静态分析完成时这些值并不可用——静态分析只能查看它面前的“代码”。因此,如果 cidr 被参数化,并且 0.0.0.0/0 在部署时传入,则安全组入站规则 0.0.0.0/0 不会被标记。

为了允许检查参数值,用户可以在通过命令行传给 cfn_nag 和 cfn_nag_scan 的 JSON 文件中指定参数值,使用 --parameter-values-path=<filename/uri> 标志。

JSON 的格式是一个单独的键 "Parameters",其值是一个字典,每个键/值对映射到 Parameters:

{
  "Parameters": {
    "Cidr": "0.0.0.0/0"
  }
}

这将把 "0.0.0.0/0" 提供给以下 Parameter:

Parameters:
  Cidr:
    Type: String

请注意,如果 JSON 中有额外的参数,它们会被静默忽略(以允许 cfn_nag_scan 将同一个 JSON 应用于所有模板)。

如果 JSON 格式错误或不符合上述规范,解析将以 FATAL 违规失败。

映射

在 0.5.55 之前,对 Fn::FindInMap 的调用实际上会被忽略。底层模型会保留它们,因此它们会以 Hash 值的形式出现在规则中。例如:{ "Fn::FindInMap" => [map1, key1, key2]}

从 0.5.55 开始,模型会尝试计算 FindInMap 调用的值,并将该值提供给规则。此评估支持以下键:

  • 静态文本
  • 对参数的引用(带参数替换)
  • 对 AWS 伪函数的引用(见下一节)
  • 嵌套映射

如果评估逻辑无法确定某个键的值,它将默认采用旧行为,即返回整个表达式的 Hash。

AWS 伪函数

同样在 0.5.55 之前,对 AWS 伪函数的调用实际上被忽略。底层模型会保留它们,因此它们会以 Hash 值的形式出现在规则中。例如:{"Ref"=>"AWS::Region"}。一个常见的用例是按区域组织映射,因此伪函数求值对于更好地支持映射评估很重要。

从 0.5.55 开始,模型将向规则提供以下 AWS 伪函数及其默认值:

'AWS::URLSuffix' => 'amazonaws.com',
'AWS::Partition' => 'aws',
'AWS::NotificationARNs' => '',
'AWS::AccountId' => '111111111111',
'AWS::Region' => 'us-east-1',
'AWS::StackId' => 'arn:aws:cloudformation:us-east-1:111111111111:stack/stackname/51af3dc0-da77-11e4-872e-1234567db123',
'AWS::StackName' => 'stackname'

此外,最终用户可以通过传统的参数替换机制覆盖所提供的值。例如:

{
  "Parameters": {
    "AWS::Region": "eu-west-1"
  }
}

控制条件的行为

在 cfn_nag 0.4.66 版本之前,底层模型不会对模板中的 Fn::If 做任何处理。这意味着,如果属性具有条件值,则需要规则来解析 Fn::If。鉴于 Fn::If 几乎可以出现在任何地方,这给规则开发者带来了一种“打地鼠”式的困境。充其量,规则逻辑可以忽略那些为 Hash 的值——前提是该值原本就不是 Hash。

为了解决此问题,cfn_nag 现在的默认行为是用 true 分支的结果替换 Fn::If。这意味着默认情况下,规则不会检查 false 分支结果中的安全违规。

除了在属性值级别替换 Fn::If 之外,同样的行为也应用于 Properties 顶层的 Fn::If。例如:

Resource1:
  Type: Foo
  Properties: !If
    - IsNone
    - Description: Up
    - Description: DOwn

看起来将与以下内容相同:

Resource1:
  Type: Foo
  Properties:
    Description: Up

为了对上述行为提供一定控制,用户可以在通过命令行传给 cfn_nag 和 cfn_nag_scan 的 JSON 文件中指定条件值,使用 --condition-values-path=<filename/uri> 标志。

该 JSON 的格式是一个字典,每个键/值对映射到 Conditions:

{
  "Condition1": true,
  "Condition2": false
}

Stelligent 策略复杂度指标(spcm)

SPCM 的基础在博客文章 IAM 策略文档复杂度度量的思想实验 中有所描述。

从 cfn_nag 0.6.0 版本开始:

下载工具