xwtro0tk1t-cloud/harness/security-review-skill-for-terraform

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

审计 Terraform / IaC 代码安全(AWS 基础设施)。检测硬编码凭据、过宽 Security Group(0.0.0.0/0)、IAM 权限过大(Action/Resource *)、S3 公开访问、RDS 未加密/公开、State 文件泄露、ECS/EKS 容器特权、CloudTrail/VPC FlowLog 缺失、不安全 Provider/Module 引用等。当审计 Terraform 代码、IaC 安全评审、AWS 云基础设施配置检查、GitOps 安全审计时使用。支持 HCL(.tf)、Terraform JSON、tfvars、Terragrunt(HCL) 代码。

Install

npx vskill@latest install xwtro0tk1t-cloud/harness/security-review-skill-for-terraform

SKILL.md

Terraform / AWS IaC Security Review

技术栈背景

Terraform (HCL) 基础设施即代码安全审计,聚焦 AWS Provider。

审计范围:

  • .tf 文件(HCL 资源定义)
  • .tfvars / terraform.tfvars(变量值文件)
  • backend.tf / provider.tf(后端和 Provider 配置)
  • modules/(自定义和第三方模块)
  • terragrunt.hcl(如使用 Terragrunt)
  • .terraform.lock.hcl(Provider 锁定文件)
  • CI/CD pipeline 中的 Terraform 步骤

关键审计维度:

  • D1: 凭据与密钥管理
  • D2: 网络安全(Security Group / NSG / Firewall)
  • D3: IAM 与访问控制
  • D4: 加密(静态 + 传输)
  • D5: 公开访问与暴露面
  • D6: State 文件安全
  • D7: Provider 与 Module 供应链
  • D8: 容器与计算资源安全
  • D9: 日志、监控与合规
  • D10: Terraform 运行时安全

审计模式

触发 skill 后,首先用 AskUserQuestion 询问用户审计模式:

问题: "选择审计模式" 选项:

  1. 全量审计 — 扫描指定目录/模块的全部 .tf 文件
  2. PR/分支审计 — 只扫描 Terraform 变更(git diff 中的 .tf/.tfvars 文件)
  3. 最近变更审计 — 扫描最近 N 天/N 个 commit 的 .tf 变更

如果用户 prompt 中已明确指定模式,跳过询问。

PR/分支模式

Step 0: 确定 diff 范围

bash
git diff --name-only <base>...<target> -- '*.tf' '*.tfvars' 'terragrunt.hcl'

Step 0.1: 范围分析

  1. 将改动 .tf 文件按模块/目录分类
  2. 对每个改动文件:Read 完整文件 + 识别新增/修改的 resource block
  3. 检查相关 variable/output/data source 引用链

审计方法

核心原则:宁可漏过也不误报。所有发现必须基于实际代码。IaC 审计特点:配置即代码——缺失安全配置本身就是漏洞。

Step 1: 侦察阶段
  1. 识别 Provider:required_providers block → AWS(主要)/ Kubernetes / Helm
  2. 识别 Backend:backend block → S3(推荐)/ Consul / Local
  3. 资源清单:列出所有 resource 和 data 类型,构建攻击面
  4. 模块依赖:module block 的 source 属性 → 本地/Registry/Git
  5. 变量流:variable → locals → resource 属性的数据流
Step 2: 正则扫描(必须执行)

根据下方"审计正则速查"逐条 Grep。IaC 正则扫描是核心检测手段——Terraform 安全问题大多是配置模式匹配。

Step 3: 双轨审计

Sink-driven(找危险配置):

  • 过宽 CIDR(0.0.0.0/0)、通配符 IAM 权限(*)、公开存储桶
  • 硬编码凭据、明文密码、未加密资源

Control-driven(找缺失的安全控制):

  • 存储资源无加密?计算资源无 IAM role?日志未启用?
  • 缺失即脆弱:应有的安全属性未设置 → 漏洞
Step 4: 数据流分析

IaC 数据流 = 变量传播:

variable "db_password" → local.config → resource.aws_db_instance.password
→ tfvars 文件中是否明文?
→ State 文件中是否存储?

追踪:

  1. variable 定义是否标记 sensitive = true
  2. 变量值来源:tfvars / 环境变量 / Vault / SSM
  3. 变量是否传入不安全的属性(如 user_data 脚本)
Step 5: 跨模块分析
  • 子模块 output 是否暴露敏感值?
  • 父模块是否信任子模块输出用于安全决策?
  • terraform_remote_state 读取是否暴露其他环境的敏感数据?
Step 6: 攻防对抗验证

攻击方:如果获得对此基础设施的只读/读写权限,能做什么? 防御方:是否有 WAF/SecurityGroup/NACL/IAM boundary 阻止?

Step 7: 覆盖评估
  • [ ] 凭据与密钥(硬编码/明文/State泄露)
  • [ ] 网络安全(SG/NACL/防火墙规则)
  • [ ] IAM 权限(最小权限/通配符/跨账户)
  • [ ] 加密(存储/传输/密钥管理)
  • [ ] 公开访问(S3/RDS/端点)
  • [ ] State 文件(远程后端/加密/访问控制)
  • [ ] Module 供应链(来源/版本/完整性)
  • [ ] 容器/计算(特权/root/资源限制)
  • [ ] 日志监控(CloudTrail/VPC FlowLog/审计)
  • [ ] 运行时安全(Provider 认证/CI 权限)
误报识别
  • 0.0.0.0/0 在 egress 规则中通常是合理的(出站全放行)
  • description 字段中包含密码样例字符串不是凭据泄露
  • terraform.tfvars.example 中的占位值不是真实凭据
  • data.aws_iam_policy_document 中 actions = ["s3:GetObject"] + resources = ["*"] 对只读 S3 可能是合理的
  • count = 0 或 for_each = {} 的资源不会实际创建
  • dynamic block 中的 content 可能有条件控制

优先检查

优先级目标原因
P0硬编码凭据/密钥直接泄露即可攻陷
P00.0.0.0/0 ingress + 敏感端口互联网直接暴露
P0IAM *:* 权限等同管理员,极度危险
P1S3 公开访问数据泄露
P1数据库/存储未加密合规 + 数据保护
P1State 文件无加密/无远程后端State 含所有密钥
P2模块来源未锁版本供应链攻击
P2日志/监控缺失无法检测攻击
P2容器特权/root容器逃逸

通用漏洞检查

D1: 凭据与密钥管理

硬编码凭据:

hcl
# 危险:明文密码
resource "aws_db_instance" "main" {
password = "MyS3cretP@ss!" # 硬编码
}
resource "aws_iam_access_key" "user" {
user = aws_iam_user.example.name
# access_key/secret_key 会存入 State
}
# 安全:引用 Secrets Manager
resource "aws_db_instance" "main" {
password = data.aws_secretsmanager_secret_version.db.secret_string
}
# 安全:标记 sensitive
variable "db_password" {
type = string
sensitive = true
}

State 文件中的密钥:

hcl
# 危险:本地 State(含所有资源属性,包括密码)
terraform {
backend "local" {} # State 文件存在本地磁盘
}
# 安全:远程 State + 加密
terraform {
backend "s3" {
bucket = "my-tf-state"
key = "prod/terraform.tfstate"
encrypt = true
dynamodb_table = "tf-locks"
}
}
D2: 网络安全

过宽 Security Group:

hcl
# 危险:全开入站
resource "aws_security_group_rule" "bad" {
type = "ingress"
from_port = 0
to_port = 65535
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
# 危险:SSH/RDP 对公网开放
resource "aws_security_group_rule" "ssh_open" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # SSH 对全互联网开放
}
# 安全:限制到 VPN/堡垒机 IP
resource "aws_security_group_rule" "ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"] # 仅内网
}

VPC Endpoint 缺失:

hcl
# 危险:S3 流量走公网(可被拦截)
# 无 aws_vpc_endpoint for s3
# 安全:VPC Endpoint 限制 S3 访问
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.ap-southeast-1.s3"
route_table_ids = [aws_route_table.private.id]
policy = jsonencode({
Statement = [{
Effect = "Allow"
Principal = "*"
Action = "s3:*"
Resource = ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"]
}]
})
}
D3: IAM 与访问控制

过宽 IAM 策略:

hcl
# 危险:管理员权限
resource "aws_iam_policy" "admin" {
policy = jsonencode({
Statement = [{
Effect = "Allow"
Action = "*" # 全部操作
Resource = "*" # 全部资源
}]
})
}
# 危险:通配符 Action
resource "aws_iam_policy" "too_wide" {
policy = jsonencode({
Statement = [{
Effect = "Allow"
Action = "s3:*" # S3 全部操作
Resource = "*"
}]
})
}
# 安全:最小权限
resource "aws_iam_policy" "minimal" {
policy = jsonencode({
Statement = [{
Effect = "Allow"
Action = ["s3:GetObject", "s3:ListBucket"]
Resource = [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}]
})
}

AssumeRole 信任过宽:

hcl
# 危险:任何 AWS 账户可 AssumeRole
resource "aws_iam_role" "bad" {
assume_role_policy = jsonencode({
Statement = [{
Effect = "Allow"
Principal = { AWS = "*" } # 任何人
Action = "sts:AssumeRole"
}]
})
}
D4: 加密

存储未加密:

hcl
# 危险:S3 无服务端加密
resource "aws_s3_bucket" "data" {
bucket = "sensitive-data"
# 缺少 server_side_encryption_configuration
}
# 危险:RDS 未加密
resource "aws_db_instance" "main" {
storage_encrypted = false # 或缺失此属性
}
# 危险:EBS 未加密
resource "aws_ebs_volume" "data" {
encrypted = false
}
# 安全
resource "aws_s3_bucket_server_side_encryption_configuration" "enc" {
bucket = aws_s3_bucket.data.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
}
}
}
D5: 公开访问与暴露面

S3 公开:

hcl
# 危险:S3 公开读
resource "aws_s3_bucket_acl" "public" {
bucket = aws_s3_bucket.data.id
acl = "public-read"
}
# 危险:S3 公开访问未阻止
resource "aws_s3_bucket_public_access_block" "bad" {
bucket = aws_s3_bucket.data.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
# 安全
resource "aws_s3_bucket_public_access_block" "secure" {
bucket = aws_s3_bucket.data.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}

数据库公开:

hcl
# 危险
resource "aws_db_instance" "public_db" {
publicly_accessible = true
}
# 危险:ElastiCache 无加密
resource "aws_elasticache_replication_group" "bad" {
at_rest_encryption_enabled = false
transit_encryption_enabled = false
}
# 危险:EKS API Server 公开
resource "aws_eks_cluster" "public" {
vpc_config {
endpoint_public_access = true
public_access_cidrs = ["0.0.0.0/0"]
}
}
D6: 配置与部署

Provider 版本未锁定:

hcl
# 危险:无版本约束
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
# 缺少 version 约束
}
}
}
# 安全
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

调试/开发模式:

hcl
# 危险:输出敏感值
output "db_password" {
value = aws_db_instance.main.password
# 缺少 sensitive = true
}
D9: 业务逻辑(资源配置)

资源无备份/版本化:

hcl
# 危险:S3 无版本化(数据可被覆盖/删除)
resource "aws_s3_bucket_versioning" "none" {
bucket = aws_s3_bucket.data.id
versioning_configuration {
status = "Disabled"
}
}
# 危险:RDS 无备份
resource "aws_db_instance" "no_backup" {
backup_retention_period = 0
}

无删除保护:

hcl
# 危险:生产数据库可被 terraform destroy 直接删除
resource "aws_db_instance" "prod" {
deletion_protection = false # 或缺失
}

深度漏洞模式

HCL 深度 Sink/Source

危险 Sink(安全敏感属性):

类别Resource.Attribute风险
凭据*.password, *.secret_key, *.access_key, *.token硬编码凭据
网络*.cidr_blocks, *.source_ranges, *.ip_range_filter过宽网络
IAM*.policy (JSON), *.actions, *.principal权限过大
加密*.encrypted, *.kms_key_id, *.sse_algorithm未加密
公开*.publicly_accessible, *.acl, *.public_access公开暴露
计算*.privileged, *.user_data, *.root_block_device容器/实例安全
日志*.logging, *.access_logs, *.trail监控缺失

Source(配置值来源):

  • variable 定义 → 检查是否 sensitive = true
  • terraform.tfvars / *.auto.tfvars → 检查是否含明文凭据
  • data source → 检查是否从不可信源读取
  • locals → 检查是否拼接生成不安全配置
  • templatefile() / user_data → 检查内嵌脚本安全
审计正则速查(Step 2 必须执行)

以下正则在 Step 2 必须逐条执行 Grep:

HCL 正则(*.tf + *.tfvars 文件)

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
325
Repository forks
45
7-day trend score
29

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 17 May 2026, 5 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/xwtro0tk1t-cloud/harness/security-review-skill-for-terraform/badge)](https://verified-skill.com/skills/xwtro0tk1t-cloud/harness/security-review-skill-for-terraform)

Something wrong with this skill or its page? Tell us.