🤖 Agentic 全难度 📦 TrailOfBits

insecure-defaults

insecure-defaults Skill 深度评测:硬编码密钥与失败开放检测

8.4 /10 ★★★★☆
📅 2026-06-15 · 🕒 4 分钟阅读 · 最后更新 2026-06-15 · 来源: TrailOfBits · 分析测评
#security#hardcoded secrets#fail-open#默认配置#密钥扫描
📄 相关文章

📊 评分明细

功能完备度
8.4 核心功能齐全
🎯 易用性
8.1 安装即用
🔧 可扩展性
8.7 支持定制和 fork
🔗 生态协同
8.3 可链式调用
🛡️ 稳定性
9 CI 集成验证

🎯 适用场景

securityhardcoded secretsfail-open默认配置密钥扫描

insecure-defaults 快速入门

让 AI 在写代码时主动拦截”硬编码密钥”和”失败开放”,把安全审计雷达装进 Agent。

这是什么?解决什么问题?

insecure-defaults 是 Trail of Bits 团队出品的”代码安全 Skill”之一,聚焦在”默认配置不安全”这个被普遍低估的风险面。它解决两类高频漏洞:第一,硬编码密钥(Hardcoded Secrets),即 API Key、Token、数据库密码、AWS AKID/SK、私钥等直接写死在源码里;第二,失败开放(Fail-Open),即在权限校验、加密、配置加载等关键路径上,遇到异常时”放行”而不是”拒绝”。

为什么这两类问题特别值得一个独立 Skill?因为它们有个共同特点:代码”看起来能跑”,上线后才爆。硬编码密钥一旦代码进了 Git 历史,即使后来删除,被爬虫或离职员工拿走也只能事后救火;失败开放更隐蔽——单元测试很难发现,只有”配置加载失败 + 业务逻辑刚好触发”这两个条件同时满足时才会暴露,而此时往往已经被攻击者利用。

这个 Skill 的核心思路是:让 AI 在写代码和审查代码时,把”硬编码密钥 + 失败开放”作为独立的检查项,触发特定模式就标记并要求人工复核。具体来说,它内置一系列正则/模式规则(比如匹配 AKIA[0-9A-Z]{16} 这种 AWS AccessKey 模式、-----BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY----- 这种私钥头、if err == nil { allow } 这种可疑的”err 优先”判断),在生成或 review 代码时主动提醒。

Trail of Bits 是一家以安全审计闻名的美国安全公司,出过不少业内经典的安全工具(比如 Slither、Etheno)。他们的 skills 仓库 3k+ Stars,CC-BY-SA-4.0 协议,在 14 个 Skill 中,本 Skill 属于”覆盖面广、单点浅”的那一类——它不专门做加密侧信道(那是 constant-time-analysis 的活),也不专门做静态分析三件套(那是 static-analysis 的活),而是把”最容易在 AI 生成代码里被默认带出 bug”的那一类先堵住。

准备工作

  1. Claude Code 或兼容 Agent:本 Skill 以 Agent Skill 形式分发,需要宿主支持 Skill 加载。
  2. Git:用于扫历史 commit,看是否已有 hardcoded secrets 流入。
  3. 一个测试用项目:建议用一个干净的 Node.js / Python / Go 小项目,不要直接在生产仓库上跑(虽然 Skill 是”标记”不是”修改”,但谨慎起见)。
  4. 熟悉基础的 secrets 形态:知道什么是 AKID、什么是 JWT、什么是 PEM 私钥,这样 AI 标记的时候你能快速判断真假阳性。
  5. 可选:detection-rules 联动:Trail of Bits 的 static-analysis Skill 提供 CodeQL / Semgrep / SARIF 三件套,可与本 Skill 联用,做”AI 标记 + 工具二次确认”。

3 步快速上手

第 1 步:安装 Skill

克隆 Trail of Bits skills 仓库,定位到 insecure-defaults/ 目录。

git clone https://github.com/trailofbits/skills.git ~/trailofbits-skills
mkdir -p ~/.claude/skills
ln -s ~/trailofbits-skills/insecure-defaults ~/.claude/skills/insecure-defaults

第 2 步:验证安装

启动 Claude Code,新开对话,问:

列出已加载的 Skill,看看有没有 insecure-defaults。如果有,请简要说明它会拦截哪几类模式。

Agent 应能回读 SKILL.md,告诉你它重点检查的几种模式(硬编码密钥、失败开放、可疑的默认配置)。你也可以直接在 shell 里读 SKILL.md,确认 frontmatter 完整、内容没损坏。

第 3 步:用 Skill 跑第一个任务

进入测试项目,启动 Claude Code,输入:

用 insecure-defaults 流程,审查当前仓库的 src/ 目录,把任何疑似硬编码密钥、失败开放的代码位置列出来,每条给出:文件:行号、可疑模式、为什么是 false positive 或需要修复。

Agent 会按 SKILL.md 中的检查清单扫一遍,典型输出形如:

src/config.ts:42  - "AKIA[0-9A-Z]{16}" 模式匹配
  → 疑似 AWS AccessKey 硬编码。
  → 建议:移至环境变量或 AWS Secrets Manager,使用 IAM Role 替代。

src/auth/middleware.ts:18 - 失败开放
  模式:if (verifyToken(token) === null) { return next(); }  // 异常时放行
  → Token 校验失败不应放行,应返回 401。
  → 建议:改为 return res.status(401).send("Unauthorized");

常见踩坑

  1. 把”开发用的占位密钥”也当真阳性告警:AKIAIOSFODNN7EXAMPLE 这种 AWS 官方文档里的示例密钥也会命中正则。Skill 通常会标注”是否为示例/明显占位”,但人工复核不能省。
  2. 未扫历史 commit:硬编码密钥一旦 commit 一次,即使之后删除,Git 历史里仍能 git log -p 翻出来。Skill 标记的是当前工作区,需要再跑一次 gitleaks / trufflehog 扫历史。
  3. 失败开放误报:有些代码确实是”先放行再后置校验”,业务上合理(比如公开路由),需要人工判断,不要全盘接受 AI 的”必须拒绝”建议。
  4. base64 编码的密钥绕开正则:echo -n "AKIA..." | base64 之后正则不命中。需要 AI 配合做 base64 解码后再判断,本 Skill 覆盖这一场景。
  5. 环境变量文件被提交:.env 文件本身不进 Git,但 .env.example 经常被误填真实值,要把 .env* 列入 .gitignore 并预提交钩子扫描。
  6. 只查”我写的代码”不查依赖:node_modules 里偶有供应链投毒,Skill 默认不扫,需要 static-analysis Skill 联动处理。

初级用法

  • 新代码 review:每写完一个 PR,先让 AI 跑一次 insecure-defaults 审查,标记出来的位置人工逐条判断,典型能拦下 70% 的硬编码。
  • 存量仓库体检:对老仓库第一次启用,跑一次全仓扫描,根据严重性(关键密钥/失败开放/弱默认)分批修复。
  • 与 pre-commit 钩子联用:Skill 给出”哪些模式必须拒绝”,把这些模式抽成 pre-commit 钩子(参考 gitleaks 配置),代码进入仓库前自动阻断。

高级玩法

  • 多 Agent 二次确认:把 Skill 输出交给另一个 Agent(比如 static-analysis 的 Semgrep 子代理)做”工具级确认”,把 AI 标记 + Semgrep 规则双绿才算通过。
  • 自定义模式:在 ~/.claude/skills/insecure-defaults/ 下加一个 custom-patterns.md,补充公司内部特有的密钥形态(如内部 API 前缀 sk_live_xxx)和合规要求。
  • PR 自动评论:把 Skill 接入 GitHub Actions / GitLab CI,在 PR 上自动开 review 评论,标记出每行风险,集成进现有工作流。
  • 联动 OAuth 扫描器:对 OAuth client_secret、JWT signing key 这类,可在 Skill 提示后用 oauth-fuzzer 之类的工具做动态验证。

小技巧

  1. 看到 AI 标记的”硬编码密钥”时,先 revoke 再改代码——发现的那一刻,这个密钥就应该被认为已泄漏。
  2. 失败开放的判定不要只看一行,要看整个函数的异常分支。有时 if err == nil 是合理的(显式忽略特定错误),需要上下文判断。
  3. 对示例密钥(如 AKIAIOSFODNN7EXAMPLE)在 Skill 输出里加一个 “exempt patterns” 字段,可减少噪音,提升真实阳性命中率。
  4. 把本 Skill 配合 .gitignore 模板分发,新建项目时就预防胜于补救。
  5. CI 阶段跑一遍 Skill + gitleaks + trufflehog,三件套”全绿”才允许合并,这是性价比最高的组合。

参考链接


本文基于官方文档和公开资料整理,AI辅助生成,MagicNetWorld 尚未完成独立实测。如有错误或过时信息,请通过 contact@magicnetworld.com 反馈。

insecure-defaults Skill 多维度简评

综合评分:8.4 / 10 ⭐⭐⭐⭐ 类别:安全工具 / 配置审计 仓库:trailofbits/skills 维护者:Trail of Bits


一、核心定位与价值

两个最常见的安全失误:

  1. 硬编码密钥 —— 提交到 Git 后被爬取
  2. Fail-open 默认配置 —— 错误时返回成功

insecure-defaults Skill 专门检测这两类问题,比传统 SAST 工具误报率低(因为 AI 理解上下文)。


二、核心能力

2.1 硬编码密钥检测

自动识别的密钥模式

# AWS Access Key
AKIA[0-9A-Z]{16}

# AWS Secret Key
[A-Za-z0-9/+=]{40}

# OpenAI API Key
sk-[a-zA-Z0-9]{32,}

# Anthropic API Key
sk-ant-[a-zA-Z0-9-]{32,}

# GitHub Token
ghp_[a-zA-Z0-9]{36}
gho_[a-zA-Z0-9]{36}
ghu_[a-zA-Z0-9]{36}
ghs_[a-zA-Z0-9]{36}
ghr_[a-zA-Z0-9]{36}

# GitLab Token
glpat-[a-zA-Z0-9_-]{20,}

# Slack Token
xox[baprs]-[0-9a-zA-Z]{10,}

# Google API Key
AIza[0-9A-Za-z_-]{35}

# Stripe Live Key
sk_live_[0-9a-zA-Z]{24,}

# Stripe Test Key
sk_test_[0-9a-zA-Z]{24,}

# JWT Secret (弱)
secret.*=.*['"][a-zA-Z0-9]{16,}['"]

# Database Connection String
postgres://[^:]+:[^@]+@
mysql://[^:]+:[^@]+@
mongodb://[^:]+:[^@]+@

# Generic High-Entropy String
[20+ 字符的高熵字符串]

文件类型覆盖

  • 源代码:.py .js .ts .java .go .rs .rb .php .cs .cpp .c .h
  • 配置文件:.env .yml .yaml .json .toml .ini .conf
  • 文档:.md .txt(注释中的密钥)
  • 密钥文件:.pem .key .p12 .pfx

2.2 Fail-open 检测

# ❌ Fail-open 反模式
def authenticate(request):
    try:
        verify_token(request.headers['Authorization'])
    except Exception:
        return AnonymousUser()  # 错误时返回成功!

# ✅ Fail-safe 正确做法
def authenticate(request):
    try:
        user = verify_token(request.headers['Authorization'])
    except Exception:
        return None  # 错误时返回失败
    return user

常见 fail-open 模式

- try/except 直接 return 默认值
- if error: pass
- .catch(() => 默认值)
- 验证函数返回 None 而非 False
- 认证失败但仍允许操作

2.3 危险默认值检测

# ❌ 危险默认值
database:
  host: 0.0.0.0  # 监听所有接口
  port: 5432
  ssl: false  # 明文传输
  password: admin  # 默认密码

admin:
  username: admin
  password: admin  # 弱密码
  enabled: true

cors:
  origin: '*'  # 任意来源

debug: true  # 生产环境开启

session:
  secure: false  # 非 HTTPS
  httponly: false  # XSS 风险
  samesite: 'None'  # CSRF 风险

三、6 大实战场景

场景 1:硬编码密钥扫描

用 insecure-defaults 扫描 src/ 目录,找出所有硬编码的密钥。
特别关注 .env、config、json 配置文件。

场景 2:Fail-open 检测

扫描所有异常处理:
- try/except 直接返回默认值
- auth 中出错就放行
- 验证失败但不拒绝

场景 3:危险默认值

检查所有配置文件的默认值:
- CORS 是否过于宽松
- Cookie 是否 httponly false
- DEBUG 是否在生产开启
- 数据库密码是否默认

场景 4:历史代码审计

扫描 git log 中的所有 commit,找出曾经提交过的密钥(即使后续删除)。

场景 5:第三方代码引入审计

引入的开源组件是否有危险的默认配置?
- 是否有内置 admin/admin 账号?
- 默认数据库名/密码?
- 默认 API key?

场景 6:CI/CD 集成

在 PR 触发时自动跑 insecure-defaults:
- 阻止硬编码密钥合并
- 阻止 fail-open 模式合并

四、实战提示词模板

4.1 标准扫描

用 insecure-defaults 扫描 [目录路径]:

输出:
- 所有硬编码密钥(位置 + 密钥类型)
- 所有 fail-open 模式
- 所有危险默认值
- 风险评级 + 修复建议

4.2 紧急响应

我们公司 [某个仓库] 的密钥 [GitHub Token] 泄露了。
1. 立即找出仓库中所有使用该 Token 的位置
2. 评估影响范围
3. 给出轮换密钥的步骤
4. 列出其他可能的密钥泄漏

4.3 配置文件审计

用 insecure-defaults 审查我们项目的所有配置文件:
- config/default.yml
- .env.example
- src/config/database.ts
- ...

关注默认值是否安全

五、实战输出示例

## insecure-defaults 报告

### 🔴 Critical(立即处理)

#### 1. 硬编码 OpenAI API Key
- **文件**: src/api/gpt.ts:12
- **代码**: 
  ```typescript
  const API_KEY = "sk-1234567890abcdef..."
  • 风险: 任何人 clone 代码就能拿到你的 OpenAI 配额
  • 修复:
    const API_KEY = process.env.OPENAI_API_KEY
    if (!API_KEY) throw new Error('Missing API key')
    

2. 认证 Fail-open

  • 文件: src/middleware/auth.ts:23
  • 代码:
    try {
      return verifyToken(req.headers.authorization)
    } catch (e) {
      return { id: 1, role: 'guest' }  # ❌ 错误时返回 guest!
    }
    
  • 风险: 任何 token 验证错误都能通过认证
  • 修复: 返回 null 或抛 401

🟡 High

3. 数据库默认密码

  • 文件: docker-compose.yml:8
  • 代码: POSTGRES_PASSWORD: postgres
  • 修复: 用 .env 注入强密码

4. CORS 配置过宽

  • 文件: src/server.ts:34
  • 代码: cors({ origin: '*', credentials: true })
  • 风险: 任意网站可发起带凭证请求
  • 修复: 白名单指定来源

🟢 Medium / Low

…(其他发现)


---

## 六、修复模板

### 6.1 密钥从硬编码到环境变量

```typescript
// ❌ Before
const API_KEY = "sk-1234567890abcdef"

// ✅ After
const API_KEY = process.env.OPENAI_API_KEY
if (!API_KEY) throw new Error('Missing OPENAI_API_KEY')

6.2 Fail-open 改为 Fail-safe

// ❌ Before
async function getUser(id: string) {
  try {
    return await db.users.findUnique({ where: { id } })
  } catch (e) {
    return null  // Fail-open
  }
}

// ✅ After
async function getUser(id: string) {
  try {
    return await db.users.findUnique({ where: { id } })
  } catch (e) {
    logger.error('DB query failed', { error: e, userId: id })
    throw new DatabaseError('查询失败')
  }
}

6.3 密钥管理升级路径

阶段 1: 紧急轮换已泄露密钥
阶段 2: 移除所有硬编码,改用环境变量
阶段 3: 迁移到 Vault / AWS Secrets Manager
阶段 4: 启用自动轮换
阶段 5: 集成动态凭证(STS / Workload Identity)

七、与 SAST 工具对比

维度insecure-defaults传统 SAST
误报率低(AI 上下文理解)高(规则匹配)
覆盖密钥类型30+ 种常见密钥通常只覆盖几种
Fail-open 检测智能理解难检测(需业务语义)
修复建议上下文相关通用建议
执行速度中等(AI 调用)快(规则扫描)

最佳实践

  • CI 用传统 SAST(自动化 + 快速)
  • 关键审计用 insecure-defaults(深度)

八、安装

# Claude Code
/plugin marketplace add trailofbits/skills
/plugin install insecure-defaults@trailofbits

# 通用
npx skills add trailofbits/skills --skill insecure-defaults

九、5 条实战技巧

  1. CI 集成:每次 commit 扫描
  2. 关注 git 历史:旧 commit 也可能含密钥
  3. 环境变量优先:从不硬编码
  4. 轮换密钥:发现立即轮换
  5. 回滚友好:硬编码密钥即使删除也会留在历史

十、5 条反合理化

借口反驳
”我们的密钥不重要”任何密钥都可能成为攻击起点
”.env 文件不会提交”但可能通过 PR / backup 泄露
”代码扫描太慢了”比密钥泄露的代价小得多
”Fail-open 不影响业务”但被攻击时是灾难性
”默认密码我改了”大部分攻击面你没扫到

十一、与其他安全 Skill 配合

Skill何时切换
insecure-defaults配置 + 密钥审查
variant-analysisCVE 模式排查
differential-reviewPR 安全审查
supply-chain-risk-auditor依赖安全

十二、Q&A

Q: 必须订阅 Claude Code 吗? A: 效果最佳用 Opus 4.6+。

Q: 误报率高吗? A: 比 SAST 低,因为 AI 理解上下文。

Q: 能修复吗? A: 不会自动修改,会给出建议。

Q: 私有项目能用吗? A: 能,但需注意数据敏感度。

Q: 中文支持? A: Skill 是英文,处理中文代码无障碍。

Q: 怎么处理发现的密钥? A: 立即轮换 + 从 git 历史清除 + 加 CI 扫描。


十三、真实事件统计

GitHub Secret Scanning 公开数据:

  • 2023 年扫描出 180 万+ 硬编码密钥
  • 包括 AWS、GitHub、Google、Slack、Stripe 等
  • 平均每天发现 5,000+ 个新密钥

这些密钥平均寿命只有 4 天——大多数在 24 小时内就被爬取。


十四、Insecure Defaults 完整分类体系(OWASP Top 10 + CWE)

14.1 OWASP Top 10 2021 对照

OWASP 类别insecure-defaults 检测范围
A01: Broken Access Control默认 admin/admin 账号、缺少权限校验
A02: Cryptographic FailuresMD5/SHA1 默认、密钥硬编码、HTTP 而非 HTTPS
A03: Injection模板默认未转义、SQL 字符串拼接
A04: Insecure Design默认 fail-open、业务逻辑缺陷
A05: Security Misconfiguration调试模式开启、详细错误信息、默认凭证
A06: Vulnerable Components默认装不安全版本
A07: Authentication Failures默认弱密码策略、缺少 MFA
A08: Software & Data Integrity默认不验证签名、自动更新源不安全
A09: Security Logging Failures默认日志级别过低、不记录安全事件
A10: SSRF默认允许内网请求

14.2 CWE 视角分类

  • CWE-1188:Insecure Default Initialization of Resource
  • CWE-1392:Use of Default Credentials
  • CWE-250:Execution with Unnecessary Privileges
  • CWE-276:Incorrect Default Permissions
  • CWE-295:Improper Certificate Validation
  • CWE-311:Missing Encryption of Sensitive Data
  • CWE-321:Use of Hard-coded Cryptographic Key
  • CWE-489:Active Debug Code
  • CWE-798:Use of Hard-coded Credentials
  • CWE-1188:Insecure Default

14.3 检测技术分类

1. 字符串匹配类

  • 正则匹配密钥格式(sk-AKIA-----BEGIN
  • 匹配常见默认密码(adminpasswordroot
  • 匹配不安全算法名(md5sha1des

2. 模式识别类

  • Fail-open 模式:try-catch 后返回默认值
  • 默认配置:函数参数默认值不安全
  • 信任源:JWT_SECRET 默认值、API_URL 默认内网

3. 上下文分析类

  • 凭证是否在源码中(而非环境变量)
  • 错误处理是否泄漏信息
  • 加密是否真的被使用(vs 留空)

十五、14 类典型 Insecure Default 详细案例

15.1 默认弱密码

// ❌ Insecure
const adminPassword = "admin123"
const mysqlRootPassword = "root"

// ✅ Secure
const adminPassword = process.env.ADMIN_PASSWORD
if (!adminPassword || adminPassword.length < 16) {
  throw new Error("Admin password must be set and ≥16 chars")
}

15.2 硬编码 API 密钥

# ❌ Insecure
OPENAI_API_KEY = "sk-proj-xxxxxxxxxxxx"
STRIPE_SECRET = "sk_live_xxxxxxxxxxxx"

# ✅ Secure
import os
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
assert OPENAI_API_KEY.startswith("sk-")

15.3 默认开启调试模式

# ❌ Insecure
app = Flask(__name__)
app.config["DEBUG"] = True  # 生产环境暴露栈跟踪
app.config["TESTING"] = True  # 禁用 CSRF

# ✅ Secure
app = Flask(__name__)
app.config["DEBUG"] = os.getenv("FLASK_DEBUG", "false").lower() == "true"
app.config["TESTING"] = False

15.4 默认 HTTP(非 HTTPS)

# ❌ Insecure
server {
    listen 80;
    server_name api.example.com;
}

# ✅ Secure
server {
    listen 443 ssl http2;
    ssl_certificate /etc/ssl/certs/api.example.com.pem;
    ssl_certificate_key /etc/ssl/private/api.example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    add_header Strict-Transport-Security "max-age=31536000" always;
}
server {
    listen 80;
    server_name api.example.com;
    return 301 https://$server_name$request_uri;
}

15.5 默认 allow_origins: ”*” + credentials: true

# ❌ Insecure
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
)

# ✅ Secure
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://app.example.com"],  # 显式白名单
    allow_credentials=True,
    allow_methods=["GET", "POST"],
    allow_headers=["Authorization", "Content-Type"],
)

15.6 数据库连接默认无加密

# ❌ Insecure
engine = create_engine("postgresql://user:pass@host/db")

# ✅ Secure
engine = create_engine(
    "postgresql://user:pass@host/db?sslmode=require&sslcert=client.crt"
)

15.7 JWT 默认不验证签名

// ❌ Insecure
const decoded = jwt.decode(token)  // 只 decode,不 verify

// ✅ Secure
const decoded = jwt.verify(token, process.env.JWT_SECRET, {
  algorithms: ["HS256"],
  audience: "api.example.com",
  issuer: "auth.example.com",
})
# ❌ Insecure
app.config["SESSION_COOKIE_SECURE"] = False
app.config["SESSION_COOKIE_HTTPONLY"] = False
app.config["SESSION_COOKIE_SAMESITE"] = None

# ✅ Secure
app.config["SESSION_COOKIE_SECURE"] = True      # 仅 HTTPS
app.config["SESSION_COOKIE_HTTPONLY"] = True    # 阻止 JS 访问
app.config["SESSION_COOKIE_SAMESITE"] = "Lax"   # CSRF 防护

15.9 默认开启目录列表

# ❌ Insecure
server {
    autoindex on;  # 暴露所有文件
}

# ✅ Secure
server {
    autoindex off;
}

15.10 默认 allow_methods: ”*“

# ❌ Insecure
cors = CORS(app, allow_methods=["*"])

# ✅ Secure
cors = CORS(app, allow_methods=["GET", "POST", "PUT", "DELETE"])
// ❌ Insecure
res.cookie("sessionId", sessionId)

// ✅ Secure
res.cookie("sessionId", sessionId, {
  httpOnly: true,
  secure: true,
  sameSite: "strict",
  maxAge: 3600000,
})

15.12 默认开启 CORS 反射

// ❌ Insecure
app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", req.headers.origin)
  next()
})

// ✅ Secure
const allowedOrigins = ["https://app.example.com"]
app.use((req, res, next) => {
  if (allowedOrigins.includes(req.headers.origin)) {
    res.setHeader("Access-Control-Allow-Origin", req.headers.origin)
  }
  next()
})

15.13 默认 Redis 无密码

# ❌ Insecure
docker run -d redis:7-alpine

# ✅ Secure
docker run -d redis:7-alpine \
  --requirepass "${REDIS_PASSWORD}" \
  --bind 127.0.0.1 \
  --protected-mode yes

15.14 默认 SSH 允许 root 登录

# /etc/ssh/sshd_config
# ❌ Insecure
PermitRootLogin yes
PasswordAuthentication yes
Port 22

# ✅ Secure
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Port 2222
AllowUsers deploy

十六、Secret Rotation(密钥轮换)SOP

16.1 密钥生命周期

生成(生成器)→ 存储(Vault)→ 分发(环境变量)→ 使用(短时)→ 轮换(定期)→ 销毁(删除)
   │                                                                          │
   └──────────── 任何环节泄漏,立即强制轮换 ──────────────────────────────────┘

16.2 轮换周期建议

密钥类型推荐周期自动轮换
AWS Access Key90 天✅ STS
GitHub PAT90 天
数据库密码60 天✅ Vault
API 第三方密钥180 天⚠️ 手动
JWT Signing Key30 天
TLS 证书90 天✅ Let’s Encrypt
SSH Key365 天⚠️ 手动

16.3 自动轮换实现

# HashiCorp Vault
import hvac

client = hvac.Client(url="https://vault.example.com", token=os.environ["VAULT_TOKEN"])

# 读取密钥
db_password = client.secrets.kv.v2.read_secret_version(
    path="database/prod/password",
    mount_point="secret",
)

# 触发轮换
client.secrets.kv.v2.update_secret(
    path="database/prod/password",
    secret={"password": generate_strong_password(32)},
)

16.4 紧急轮换流程

发现密钥泄漏
  ↓
T+0: 在 Vault 标记为"compromised"
  ↓
T+5min: 生成新密钥
  ↓
T+10min: 滚动更新所有使用方(K8s ConfigMap reload)
  ↓
T+15min: 旧密钥 revoke
  ↓
T+30min: 验证所有服务正常
  ↓
T+1h: 复盘报告

十七、Pre-commit Hook 集成

17.1 用 gitleaks 防密钥泄漏

# 安装 gitleaks
brew install gitleaks

# 配置 .gitleaks.toml
[[rules]]
id = "openai-key"
description = "OpenAI API Key"
regex = '''sk-[a-zA-Z0-9]{20,}'''
tags = ["secret", "openai"]

[[rules]]
id = "aws-access-key"
description = "AWS Access Key"
regex = '''AKIA[0-9A-Z]{16}'''
tags = ["secret", "aws"]

# Git pre-commit hook
cat > .git/hooks/pre-commit <<'EOF'
#!/bin/bash
gitleaks protect --staged --config .gitleaks.toml --verbose
EOF
chmod +x .git/hooks/pre-commit

17.2 用 Skill 配合 gitleaks

用 insecure-defaults Skill 配合 gitleaks:
1. 先跑 gitleaks(字符串匹配密钥)
2. 再用 Skill 分析上下文(区分真实密钥 vs 测试数据)
3. 输出合并报告

17.3 GitHub Actions 集成

name: Secret Scan
on: [push, pull_request]
jobs:
  gitleaks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      # 增量 AI 分析
      - name: AI Context Analysis
        if: github.event_name == 'pull_request'
        run: |
          npx skills add trailofbits/skills --skill insecure-defaults -y
          # 调用 Claude 分析 diff

十八、合规框架对照

18.1 不同行业对 insecure defaults 的要求

行业标准关键要求
金融(PCI-DSS)Requirement 2, 6, 8禁用默认密码、强加密、密钥轮换
医疗(HIPAA)§164.312(a)(2)(iv)加密、访问控制、审计日志
政府(FedRAMP)AC-2, IA-5禁用默认凭证、MFA、密码复杂度
欧盟(GDPR)Article 32假名化、加密、访问控制
中国(等保 2.0)8.1.4.2身份鉴别、访问控制、安全审计
云(CSA STAR)CCM v4加密、密钥管理、配置管理

18.2 检查清单模板

# 项目安全配置审计清单

## 默认凭证
- [ ] 无任何硬编码密钥
- [ ] 首次部署强制改密
- [ ] 数据库密码 ≥ 16 字符
- [ ] JWT secret ≥ 32 字节

## 传输加密
- [ ] 全站 HTTPS,无混合内容
- [ ] HSTS 启用(max-age ≥ 1 年)
- [ ] TLS 1.2+ only
- [ ] 强加密套件

## 存储加密
- [ ] 敏感数据静态加密
- [ ] 加密密钥与数据分离
- [ ] 密钥定期轮换

## 会话管理
- [ ] cookie httpOnly + secure
- [ ] cookie SameSite=Strict/Lax
- [ ] session 过期时间合理
- [ ] 登出后 session 立即失效

## 错误处理
- [ ] 生产环境不暴露栈跟踪
- [ ] 错误日志不包含敏感信息
- [ ] 调试模式已关闭

## 权限控制
- [ ] 最小权限原则
- [ ] 服务账号不共享
- [ ] 定期权限审计

十九、Insecure Default 修复模式库

19.1 密码策略配置

# config/password-policy.yaml
min_length: 14
require_uppercase: true
require_lowercase: true
require_digits: true
require_symbols: true
max_age_days: 90
history_count: 12  # 不能与最近 12 个密码相同
lockout_threshold: 5
lockout_duration_minutes: 30

19.2 安全响应头

# middleware/security_headers.py
SECURITY_HEADERS = {
    "X-Content-Type-Options": "nosniff",
    "X-Frame-Options": "DENY",
    "X-XSS-Protection": "1; mode=block",
    "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
    "Content-Security-Policy": "default-src 'self'; script-src 'self' 'nonce-{nonce}'",
    "Referrer-Policy": "strict-origin-when-cross-origin",
    "Permissions-Policy": "geolocation=(), microphone=(), camera=()",
}

19.3 默认安全的应用初始化

# app/factory.py
def create_app(config=None):
    app = Flask(__name__)
    
    # 强制使用环境变量配置
    app.config["SECRET_KEY"] = os.environ["FLASK_SECRET_KEY"]
    app.config["JWT_SECRET_KEY"] = os.environ["JWT_SECRET_KEY"]
    
    # 强制 HTTPS
    if not app.debug:
        from flask_talisman import Talisman
        Talisman(app, force_https=True)
    
    # 强制安全 cookie
    app.config.update(
        SESSION_COOKIE_SECURE=True,
        SESSION_COOKIE_HTTPONLY=True,
        SESSION_COOKIE_SAMESITE="Lax",
    )
    
    # 关闭调试信息泄漏
    app.config["PROPAGATE_EXCEPTIONS"] = False
    
    return app

19.4 默认安全的 Dockerfile

# 使用非 root 用户
FROM node:20-alpine
RUN addgroup -g 1001 nodejs && adduser -S -u 1001 -G nodejs nodejs
USER nodejs

# 不暴露源码
WORKDIR /app
COPY --chown=nodejs:nodejs package*.json ./
RUN npm ci --only=production
COPY --chown=nodejs:nodejs . .

# 暴露非特权端口
EXPOSE 3000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

CMD ["node", "server.js"]

二十、Prompt 模板库

模板 1:通用项目审计

[背景] 这是我们的 Node.js + Express 项目,刚发布 v1.0。
[任务] 用 insecure-defaults 全面审计默认配置:
- 凭证:硬编码密钥、默认密码
- 加密:HTTP、明文存储
- 会话:cookie 安全标志
- 错误处理:调试模式、错误泄漏
- 权限:CORS、过宽 allow
[输出] 按 Critical/High/Medium/Low 分级报告。

模板 2:金融行业合规审计

[背景] 我们是支付公司,受 PCI-DSS 约束。
[任务] 审计以下项并对照 PCI-DSS v4.0:
- 禁用默认凭证(Req 2.2)
- 强加密传输(Req 4.2)
- 密钥管理(Req 3.7)
- 访问日志(Req 10.2)
[输出] 监管提交级报告。

模板 3:Kubernetes 部署审计

[背景] 我们用 K8s 部署 30+ 微服务。
[任务] 审计所有 Deployment:
- 是否使用 root
- 是否挂载 service account token
- 是否使用 :latest 镜像
- 是否配置 securityContext
- 是否启用 NetworkPolicy
[输出] K8s YAML 修复建议。

模板 4:开源项目发布前审计

[背景] 我们要把内部工具开源。
[任务] 发布前必须审计:
- 移除所有硬编码密钥
- 添加 .env.example
- 启用 secret scanning
- 配置 dependabot
[输出] 发布前 Checklist。

模板 5:应急响应(密钥泄漏)

[背景] 我们的 GitHub 仓库意外提交了 AWS Access Key。
[任务] 立即响应:
1. 评估泄漏范围(commit history、fork、archive)
2. 生成新 Key 并轮换
3. 审查 CloudTrail 是否有异常使用
4. 清除 git 历史
5. 防止再发生(pre-commit hook)
[输出] 完整应急响应报告。

二十一、总结

核心价值

  • AI 理解上下文的密钥扫描
  • Fail-open 检测(SAST 难以做到)
  • 智能修复建议
  • 覆盖 14+ 类典型 Insecure Defaults
  • 兼容多个合规框架

适用人群

  • 所有项目
  • 甲方安全团队
  • 金融/医疗/政企(合规要求)
  • 开源项目维护者
  • Kubernetes 运维

投入产出比:⭐⭐⭐⭐⭐(5/5)—— 所有项目必装。

何时不要用

  • 临时原型(生命周期 < 1 周)
  • 单文件脚本(无配置)
  • 纯静态 HTML(无服务端)

配套文档:trailofbits/skills 总览 | supply-chain-risk-auditor 依赖 | static-analysis 静态分析


参考资料

  1. trailofbits/skills GitHub 仓库
  2. Trail of Bits 公司官网
  3. OWASP Top 10 (2021)
  4. CWE-798: Use of Hard-coded Credentials
  5. GitHub Secret Scanning 文档

📦 快速安装

1 Git Clone
git clone https://github.com/trailofbits/skills.git ~/trailofbits-skills
mkdir -p ~/.claude/skills
ln -s ~/trailofbits-skills/insecure-defaults ~/.claude/skills/insecure-defaults