安全审计工作流

Claude Code 工作流专题 · 自动化安全审查与漏洞检测

专题:Claude Code 工作流系统学习

关键词:Claude Code, 安全审计, SAST, Semgrep, CodeQL, Dependabot, OWASP, 密钥检测, GitLeaks

本专题涵盖:SAST静态分析 | 依赖漏洞扫描 | 密钥凭证检测 | 安全最佳实践 | CI/CD安全集成 | CLAUDE.md安全规则

一、安全审计工作流概述

安全审计是软件开发生命周期中至关重要的环节。Claude Code 作为AI驱动的编码助手,不仅可以辅助编写代码,还能深度集成安全审计工作流,帮助开发团队在编码阶段就发现并修复安全漏洞。安全审计工作流的核心理念是"左移安全"(Shift Left Security),即在开发早期介入安全检测,降低修复成本。

核心原则:安全审计不是一次性的检查,而是贯穿开发全生命周期的持续过程。Claude Code 能够在代码编写、审查、提交、构建的每个环节提供安全分析能力。

安全审计工作流的六大支柱

编号支柱领域核心工具/技术检测重点
1代码安全扫描(SAST)Semgrep, CodeQL, Bandit, ESLint代码层面的安全漏洞
2依赖漏洞扫描Dependabot, Snyk, Trivy, OSV-Scanner第三方库已知漏洞
3密钥与凭证检测GitLeaks, Talisman, Secretlint硬编码密钥和凭证泄露
4安全最佳实践实施OWASP Top 10, 安全编码规范架构设计安全缺陷
5安全CI/CD集成GitHub Actions, GitLab CI, Jenkins流水线安全门禁
6CLAUDE.md规则配置Claude Code 项目规则AI辅助安全编码约束

"安全审计不是开发流程的障碍,而是质量保证的基石。优秀的团队将安全内建于开发的每一个环节。"

二、代码安全扫描(SAST静态分析)

静态应用安全测试(SAST)通过分析源代码在不执行程序的情况下发现安全漏洞。这种白盒测试方法能够覆盖代码路径广泛,发现注入、跨站脚本、缓冲区溢出等常见漏洞。

2.1 Semgrep 配置与规则

Semgrep 是一款轻量级、高性能的静态分析工具,支持自定义规则和社区规则库。以下是一个完整的 Semgrep 配置示例:

# .semgrep.yml — Semgrep 安全审计规则配置 rules: # ── Python 安全规则 ── - id: python-eval-detected pattern: eval($X) message: "检测到 eval() 使用,可能导致代码注入攻击" severity: ERROR languages: [python] paths: exclude: - "tests/" - "*/test_*" - id: python-sql-injection patterns: - pattern-inside: | $CURSOR.execute("...$VAR..." , ...) - pattern-not: | $CURSOR.execute("..." , (...,)) message: "SQL 查询使用了字符串格式化,可能存在 SQL 注入风险" severity: ERROR languages: [python] - id: python-hardcoded-password pattern-either: - pattern: password = "..." - pattern: passwd = "..." - pattern: pwd = "..." message: "检测到硬编码密码,请使用环境变量或密钥管理服务" severity: WARNING languages: [python] paths: exclude: - "tests/" - "config/defaults.py" # ── JavaScript/TypeScript 安全规则 ── - id: js-dom-xss-innerhtml pattern-either: - pattern: document.getElementById($X).innerHTML = "..." - pattern: document.querySelector($X).innerHTML = "..." - pattern: $Y.innerHTML = "..." message: "使用 innerHTML 可能导致 XSS 攻击,建议使用 textContent 或 sanitize" severity: WARNING languages: [javascript, typescript] - id: js-no-serialize-user-input patterns: - pattern: JSON.parse($INPUT) - metavariable-regex: metavariable: $INPUT regex: .*(req|request|body|params|query).* message: "直接解析用户输入为 JSON 可能导致原型污染攻击" severity: WARNING languages: [javascript, typescript] # ── Java/Kotlin 安全规则 ── - id: java-command-injection patterns: - pattern: Runtime.getRuntime().exec($X) - metavariable-regex: metavariable: $X regex: .*(\+|concat|format).* message: "使用用户输入拼接命令可能导致命令注入攻击" severity: ERROR languages: [java]

2.2 在 Claude Code 中运行 Semgrep

Claude Code 可以通过 Bash 工具直接调用 Semgrep,并将结果解析后指导修复:

# 安装 Semgrep pip install semgrep # 运行全面扫描 semgrep --config=auto --error --output=semgrep-report.json --json . # 使用自定义规则集 semgrep --config=.semgrep.yml \ --config=p/python \ --config=p/javascript \ --config=p/java \ --severity=ERROR \ --output=semgrep-results.json --json . # 扫描结果分析(Claude Code 可解析 JSON 输出) semgrep --config=auto --json . | jq '.results[] | {file: .path, line: .start.line, severity: .extra.severity, message: .extra.message}'

2.3 CodeQL 高级查询

CodeQL 是 GitHub 出品的语义代码分析引擎,能够精确检测复杂安全漏洞。以下是一些关键的 CodeQL 查询:

# CodeQL 查询:检测 JavaScript 中未经过滤的 window.location 赋值 import javascript from Assignment a, DataFlow::SourceNode source where source = a.getRhs() and a.getLhs().(VarAccess).getVariable().getName() = "window.location" and exists(DataFlow::SourceNode u | u = source and not exists(Sanitizer s | s.sanitizes(u)) ) select a, "window.location 赋值来源未经净化,可能导致开放重定向漏洞" # CodeQL 查询:检测 Python 中的路径遍历 import python from FunctionCall fc, DataFlow::Node input where fc.getFunc().(Attribute).getName() = "open" and input = fc.getArg(0) and input = any(DataFlow::Node n | n = DataFlow::globalVarRef("request").getAPropertyRead("files").getAPropertyRead("filename")) and not exists(Sanitizer s | s.sanitizes(input)) select fc, "文件路径来自用户上传且未经过滤,存在路径遍历风险"

2.4 ESLint 安全规则集成

使用 eslint-plugin-security 为 JavaScript/TypeScript 项目添加安全 lint 检查:

// .eslintrc.js — 安全规则配置 module.exports = { plugins: ['security'], extends: ['plugin:security/recommended'], rules: { // 检测不安全的正则表达式(ReDoS 攻击) 'security/detect-unsafe-regex': 'error', // 检测 eval() 使用 'security/detect-eval-with-expression': 'error', // 检测不安全的 Buffer 操作 'security/detect-buffer-noassert': 'error', // 检测 child_process 使用 'security/detect-child-process': 'warn', // 检测 non-literal require/import 'security/detect-non-literal-require': 'error', 'security/detect-non-literal-fs-filename': 'error', // 检测对象注入风险 'security/detect-object-injection': 'warn', // 检测新的危险函数 'security/detect-new-buffer': 'error', // 检测 disabled 的 HTTPS 检查 'security/detect-disable-ssl-verify': 'error', }, overrides: [ { files: ['src/**/*.ts', 'src/**/*.tsx'], rules: { 'security/detect-object-injection': 'off', }, }, ], };

2.5 Python Bandit 安全扫描

Bandit 是 Python 项目的专用安全扫描工具,集成到 Claude Code 工作流中的方式:

# Bandit 配置文件 .bandit.yml skips: ['B101', 'B303'] exclude_dirs: - 'tests' - 'venv' - '.venv' - 'migrations' - 'node_modules' tests: - 'B101' # assert 使用 - 'B102' # exec 使用 - 'B103' # set_bad - 'B301' # pickle - 'B302' # marshal - 'B303' # md5 - 'B304' # ciphers - 'B305' # cipher_modes - 'B306' # mktemp_q - 'B307' # eval - 'B308' # mark_safe - 'B309' # https_connection - 'B310' # urllib_urlopen - 'B311' # random - 'B312' # telnetlib - 'B313' # xml_bad_cElementTree - 'B314' # xml_bad_ElementTree - 'B315' # xml_bad_expatreader - 'B316' # xml_bad_expatbuilder - 'B317' # xml_bad_sax - 'B318' # xml_bad_minidom - 'B319' # xml_bad_pulldom - 'B320' # xml_bad_etree - 'B321' # ftplib - 'B322' # input - 'B323' # unverified_context - 'B324' # server_side_ssl - 'B325' # tempnam # 运行扫描命令 # bandit -r src/ -f json -o bandit-report.json -c .bandit.yml

2.6 敏感信息泄露扫描

在代码中扫描可能的敏感信息泄露模式,Claude Code 可使用 Grep 工具配合自定义正则实现:

# 扫描常见的敏感信息泄露模式 # API Key 模式 grep -rnP '(?i)(api[_-]?key|apikey|api[_-]?secret)[\s]*[:=][\s]*["'"'"'](?![$]{)[^"'"'"']+["'"'"']' src/ --include='*.{py,js,ts,java,go,rs}' -l # AWS Access Key 模式 grep -rnP 'AKIA[0-9A-Z]{16}' src/ --include='*' -l # 私钥文件检测 find . -name '*.pem' -o -name '*.key' -o -name '*-private' 2>/dev/null | grep -v node_modules | grep -v '.git/' # 数据库连接串 grep -rnP '(postgres|mysql|mongodb|redis)://[^:]+:[^@]+@' src/ --include='*.{py,js,ts,yaml,yml,env}' -l # OAuth Token grep -rnP '(gh[pousr]_[A-Za-z0-9]{36,}|github_pat_[A-Za-z0-9]{36,})' . -l 2>/dev/null # .env 文件提交检测 find . -not -path './.git/*' -name '.env' 2>/dev/null | grep -v '.env.example' | grep -v '.env.dist'

警告:敏感信息泄露一旦被推送到远程仓库,即使后续删除,也可能已经暴露在 Git 历史中。务必在预提交阶段做好检测拦截。

三、依赖漏洞扫描

现代软件项目高度依赖第三方库,这些依赖可能引入已知的安全漏洞。依赖漏洞扫描是安全审计工作流中不可或缺的环节,Claude Code 可以帮你自动分析依赖关系、检查已知漏洞并提供修复建议。

3.1 Dependabot 配置

Dependabot 是 GitHub 内置的依赖更新工具,自动检测并创建安全更新的 PR:

# .github/dependabot.yml — 完整配置示例 version: 2 updates: # ── npm 依赖 ── - package-ecosystem: "npm" directory: "/" schedule: interval: "weekly" day: "monday" time: "09:00" timezone: "Asia/Shanghai" open-pull-requests-limit: 10 reviewers: - "team-security" labels: - "dependencies" - "security" # 版本更新策略 versioning-strategy: increase # 允许的更新类型 allow: - dependency-type: "direct" - dependency-type: "indirect" # 忽略特定类型的更新 ignore: - dependency-name: "lodash" versions: ["4.x"] # 安全更新专用配置 commit-message: prefix: "fix" prefix-development: "chore" include: "scope" # 对生产依赖和非生产依赖分组 groups: production-deps: dependency-type: "production" update-types: - "minor" - "patch" dev-deps: dependency-type: "development" update-types: - "minor" - "patch" # ── Python pip 依赖 ── - package-ecosystem: "pip" directory: "/" schedule: interval: "weekly" open-pull-requests-limit: 10 labels: - "dependencies" - "python" # ── Docker 基础镜像 ── - package-ecosystem: "docker" directory: "/" schedule: interval: "weekly" # ── GitHub Actions ── - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly"

3.2 Trivy 综合扫描

Trivy 支持多种语言和容器镜像的漏洞扫描,输出格式丰富:

# 安装 Trivy # macOS: brew install trivy # Linux: sudo apt install trivy 或下载二进制 # 扫描文件系统 trivy fs --severity=CRITICAL,HIGH --output=trivy-report.json --format=json . # 扫描容器镜像 trivy image --severity=CRITICAL --ignore-unfixed --output=image-scan.json python:3.12 # 扫描 Git 仓库 trivy repo --severity=HIGH,CRITICAL https://github.com/org/repo.git # 生成 HTML 报告 trivy fs --format=template --template "@contrib/html.tpl" -o report.html . # 只输出固定等级的漏洞 trivy fs --severity=CRITICAL --ignore-unfixed --no-progress . 2>&1 | grep -E '(Total|CRITICAL|HIGH):' # CVE 详情查看 trivy fs --severity=CRITICAL --list-all-pkgs .

3.3 OSV-Scanner 开源漏洞扫描

OSV-Scanner 使用 Google 的 OSV 数据库,精确匹配项目依赖的漏洞:

# 安装 OSV-Scanner go install github.com/google/osv-scanner/cmd/osv-scanner@latest # 扫描项目的 lock 文件 osv-scanner --lockfile=package-lock.json --output=osv-results.json --format=json # 递归扫描所有 lock 文件 osv-scanner --recursive --output=full-scan.json . # 输出格式化为表格 osv-scanner --format=table --recursive . # CI/CD 中阻断模式(存在漏洞则退出码非0) osv-scanner --recursive --fail-on-any-vulnerability . # 仅扫描生产依赖 osv-scanner --lockfile=package-lock.json --only-packages=packages

3.4 Grype 漏洞扫描器

Grype 是 Anchore 出品的快速漏洞扫描器,支持 CycloneDX SBOM 格式:

# 安装 Grype # curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin # 扫描文件系统 grype . --severity=critical,high --output=json > grype-report.json # 生成 CycloneDX SBOM 并扫描 synddt . -o cyclonedx-json > sbom.json grype sbom:sbom.json --output=table # 输出为 SARIF 格式(集成 GitHub Security Tab) grype . --output=sarif > grype-results.sarif # 基于 CVSS 评分过滤 grype . --only-fixed --fail-on=high --cvss-score=7 # 排除特定 CVE grype . --exclude "CVE-2023-1234" --exclude "GHSA-xxxx-xxxx-xxxx"

3.5 严重性分级与修复优先级

建立系统化的漏洞严重性分级方案和修复流程,确保关键漏洞第一时间处理:

等级CVSS 评分修复时限示例修复流程
CRITICAL9.0-10.024小时内远程代码执行立即修复→Code Review→部署
HIGH7.0-8.972小时内SQL注入、认证绕过当天修复→Code Review→下次部署
MEDIUM4.0-6.92周内XSS需要交互排入迭代任务,随下个版本修复
LOW0.1-3.91个月内信息泄露、日志打印记录问题列表,定期批量修复
# 自动修复优先级脚本 #!/bin/bash # automate-security-fix.sh — Claude Code 辅助的安全修复自动化 REPORT_FILE="dependency-report.json" PRIORITY_FILE="fix-priority.md" # 解析 Trivy 报告,按严重性排序 cat > $PRIORITY_FILE << 'HEADER' # 依赖漏洞修复优先级 | 优先级 | CVE ID | 严重性 | 包名 | 当前版本 | 修复版本 | 说明 | |--------|--------|--------|------|----------|----------|------| HEADER jq -r '.Results[]?.Vulnerabilities[]? | [.Severity, .VulnerabilityID, .PkgName, .InstalledVersion, .FixedVersion, .Title] | @tsv' $REPORT_FILE 2>/dev/null \ | sort -k1 \ | while IFS=$'\t' read -r sev cve pkg cur fix title; do echo "| $sev | $cve | $pkg | $cur | $fix | ${title:0:80} |" >> $PRIORITY_FILE done echo "修复优先级报告已生成: $PRIORITY_FILE" echo "CRITICAL 漏洞数: $(grep -c '| CRITICAL |' $PRIORITY_FILE)" echo "HIGH 漏洞数: $(grep -c '| HIGH |' $PRIORITY_FILE)"

最佳实践:在 Claude Code 的 CLAUDE.md 中配置依赖漏洞扫描规则,使 Claude 在每次代码修改时自动检查所涉依赖是否存在已知漏洞,并给出修复建议。

四、密钥与凭证检测

硬编码密钥和凭证泄露是导致数据泄露事件的主要原因之一。密钥检测工作流的目标是在代码提交到远程仓库之前就发现并阻止凭证泄露。

4.1 GitLeaks 全面配置

GitLeaks 是专为检测 Git 仓库中密钥泄露设计的工具,支持自定义规则和多种输出格式:

# .gitleaks.toml — GitLeaks 自定义规则配置 title = "GitLeaks 安全审计配置" # 自定义允许列表 [allowlist] description = "测试和示例文件中的假凭证" paths = [ '''(test|spec|__tests__).*\.(py|js|ts|java)''', '''examples/.*''', '''docs/.*\.md$''', ] # AWS 访问密钥 [[rules]] id = "aws-access-key" description = "AWS Access Key ID" regex = '''(?:A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}''' tags = ["aws", "credentials"] # AWS 秘密密钥 [[rules]] id = "aws-secret-key" description = "AWS Secret Access Key" regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]''' tags = ["aws", "credentials"] # GitHub Token [[rules]] id = "github-token" description = "GitHub Personal Access Token" regex = '''(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{36,}''' tags = ["github", "credentials"] # GitLab Token [[rules]] id = "gitlab-token" description = "GitLab Personal Access Token" regex = '''glpat-[A-Za-z0-9\-_]{20,}''' tags = ["gitlab", "credentials"] # Slack Token [[rules]] id = "slack-token" description = "Slack Bot/Legacy Token" regex = '''xox[baprs]-[0-9]{12}-[0-9]{12}-[0-9]{12}-[a-f0-9]{32}''' tags = ["slack", "credentials"] # Google API Key [[rules]] id = "google-api-key" description = "Google API Key" regex = '''AIza[0-9A-Za-z\-_]{35}''' tags = ["google", "api-key"] # JWT Token [[rules]] id = "jwt-token" description = "JSON Web Token" regex = '''eyJ[A-Za-z0-9\-_]{10,}\.eyJ[A-Za-z0-9\-_]{10,}\.[A-Za-z0-9\-_]{10,}''' tags = ["jwt", "token"] # Stripe API Key [[rules]] id = "stripe-api-key" description = "Stripe API Key" regex = '''(?i)sk_live_[0-9a-z]{24,}''' tags = ["stripe", "api-key"] # 运行命令 # gitleaks detect --source . --verbose --report-path=gitleaks-report.json # gitleaks protect --staged --verbose

4.2 Talisman 预提交钩子

Talisman 可以在每次提交时检查敏感信息,安装和配置方式:

# 安装 Talisman(全局) curl --silent https://raw.githubusercontent.com/thoughtworks/talisman/master/global/install.sh | bash # 或者作为项目预提交钩子 npm install --save-dev talisman # .talismanrc — Talisman 配置文件 fileignoreconfig: - filename: "package-lock.json" checksum: "SKIP" - filename: "yarn.lock" checksum: "SKIP" - filename: "*.min.js" checksum: "SKIP" - filename: "*.map" checksum: "SKIP" - filename: "test/fixtures/*" checksum: "SKIP" - filename: "docs/*.md" checksum: "SKIP" scopeconfig: - scope: "node_modules" - scope: ".git" # 自定义检测模式 custom_patterns: - name: "自定义密钥模式" pattern: "AIza[0-9A-Za-z\\\\-_]{35}" message: "检测到疑似 Google API Key" - name: "自定义连接串" pattern: "jdbc:mysql://.*password=" message: "检测到数据库连接字符串含密码"

4.3 Secretlint 轻量级检测

Secretlint 是 Node.js 生态的密钥检测工具,适合与 npm 项目集成:

# 安装 Secretlint npm install --save-dev @secretlint/secretlint \ @secretlint/secretlint-rule-preset-recommend \ @secretlint/secretlint-formatter-sarif # .secretlintrc.json — 配置 { "rules": [ { "id": "@secretlint/secretlint-rule-preset-recommend" }, { "id": "@secretlint/secretlint-rule-aws", "options": { "allows": ["AKIAIOSFODNN7EXAMPLE"] } }, { "id": "@secretlint/secretlint-rule-gcp", "options": {} }, { "id": "@secretlint/secretlint-rule-privatekey", "options": {} }, { "id": "@secretlint/secretlint-rule-basicauth", "options": {} } ] } # package.json 脚本配置 # "scripts": { # "secretlint": "secretlint '**/*' --secretlintrc .secretlintrc.json", # "secretlint:staged": "secretlint $(git diff --cached --name-only --diff-filter=ACM)" # } # 运行扫描 npx secretlint "src/**/*" --format=sarif --output=secretlint-results.sarif # 与 pre-commit 钩子集成 # npx secretlint $(git diff --cached --name-only) --quiet

4.4 pre-commit 钩子集成

将所有密钥检测工具整合到 Git 预提交钩子中,实现提交前的自动检测拦截:

# .pre-commit-config.yaml — 完整的预提交安全钩子配置 repos: # ── 通用预提交钩子 ── - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files - id: check-merge-conflict - id: detect-private-key - id: check-executables-have-shebangs # ── GitLeaks 密钥检测 ── - repo: https://github.com/gitleaks/gitleaks rev: v8.18.2 hooks: - id: gitleaks args: ['--verbose', '--config=.gitleaks.toml'] # ── Talisman 凭证检测 ── - repo: https://github.com/thoughtworks/talisman rev: v1.31.0 hooks: - id: talisman-commit entry: bash -c 'talisman --githook pre-commit' language: system # ── Secretlint ── - repo: local hooks: - id: secretlint name: secretlint entry: npx secretlint language: system files: \.(js|ts|py|java|go|rs|yaml|yml|json|env)$ # ── TruffleHog 额外密钥检测 ── - repo: https://github.com/trufflesecurity/trufflehog rev: v3.63.0 hooks: - id: trufflehog args: ['--only-verified', '--fail'] # 安装所有钩子 # pre-commit install # pre-commit install --hook-type pre-push # 手动运行检查所有文件 # pre-commit run --all-files # 仅运行安全相关的钩子 # pre-commit run gitleaks --all-files # pre-commit run secretlint --all-files

4.5 历史 Git 提交的密钥扫描

使用 Claude Code 配合 Git 工具对历史提交进行密钥扫描,发现已经泄露的凭证:

# 扫描所有历史提交中的密钥 gitleaks detect --source . --verbose --report-path=history-scan.json # 使用 trufflehog 扫描完整 Git 历史 trufflehog git file://. --results=verified --json > trufflehog-results.json # BFG Repo-Cleaner 从历史中移除敏感文件 # 1. 创建替换映射 echo 'AKIA123456789EXAMPLE==>AKIA_REMOVED' > replacements.txt # 2. 运行 BFG java -jar bfg.jar --replace-text replacements.txt .git # 3. 清理历史 git reflog expire --expire=now --all && git gc --prune=now --aggressive # 4. 强制推送 # git push --force --all

安全警告:一旦密钥被推送到远程仓库,应视为已泄露。即使从 Git 历史中移除,密钥也可能已被外部方捕获。正确做法是立即到相关平台(AWS、GitHub、Stripe等)撤销密钥并轮换。

五、安全最佳实践实施

遵循安全编码最佳实践是预防安全漏洞的根本。OWASP Top 10 是最被广泛接受的安全编码指南,Claude Code 可以在编码过程中持续引导开发者规避这十大风险。

5.1 OWASP Top 10 检测清单

编号漏洞类别检测策略Claude Code 辅助方式
A01访问控制失效权限检查覆盖测试生成测试用例覆盖所有角色
A02加密机制失效HTTPS强制、密码哈希检查审查密码存储方案是否合规
A03注入攻击参数化查询检查标记所有字符串拼接的SQL查询
A04不安全的设计威胁建模评审协助进行威胁建模分析
A05安全配置错误CSP、安全头检查推荐安全默认配置
A06易受攻击的组件依赖漏洞扫描提示更新已知漏洞的依赖
A07身份认证失效MFA、Session管理检查审查认证流程实现
A08数据完整性失效CI/CD签名、序列化检查检查数据完整性验证逻辑
A09日志和监控不足安全事件日志审查建议关键操作日志记录
A10SSRFURL校验、网络隔离检查外部请求URL来源验证

5.2 SQL 注入防御

Claude Code 可以检测并自动修复 SQL 注入漏洞,推荐使用参数化查询:

# ── 不安全的写法(易受 SQL 注入攻击)── def get_user_profile(user_id): query = f"SELECT * FROM users WHERE id = '{user_id}'" cursor.execute(query) return cursor.fetchone() # ── 安全的写法(使用参数化查询)── def get_user_profile(user_id): query = "SELECT * FROM users WHERE id = %s" cursor.execute(query, (user_id,)) return cursor.fetchone() # ── Node.js 不安全的写法 ── // 不安全 const query = `SELECT * FROM users WHERE id = '${userId}'`; connection.query(query); // 安全(使用占位符) const query = 'SELECT * FROM users WHERE id = ?'; connection.execute(query, [userId]); // 安全(使用 ORM 参数化) const user = await User.findByPk(userId); # ── Java 不安全的写法 ── // 不安全 Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM users WHERE id = '" + userId + "'"); // 安全(使用 PreparedStatement) PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?"); pstmt.setString(1, userId); ResultSet rs = pstmt.executeQuery();

5.3 XSS 防御配置

跨站脚本(XSS)攻击是最常见的 Web 安全漏洞之一。Claude Code 可以帮助实施多层防御策略:

// ── Content Security Policy 配置 ── // 严格的 CSP 头(推荐生产环境使用) // Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; font-src 'self'; frame-ancestors 'none'; form-action 'self' // Express.js 中使用 helmet 设置安全头 const helmet = require('helmet'); app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", "data:"], connectSrc: ["'self'"], fontSrc: ["'self'"], frameAncestors: ["'none'"], formAction: ["'self'"], upgradeInsecureRequests: [], }, }, // 其他安全头 hsts: { maxAge: 63072000, includeSubDomains: true, preload: true }, frameguard: { action: 'deny' }, noSniff: true, xssFilter: true, })); // ── 输出编码示例 ── // React 默认对 JSX 输出编码,防止 XSS function UserProfile({ user }) { // 安全:React 自动编码 HTML 实体 return
{user.bio}
; } // 危险:dangerouslySetInnerHTML 需谨慎使用 function RichContent({ html }) { // 必须经过 DOMPurify 净化 const sanitized = DOMPurify.sanitize(html); return
; } // ── Vue.js 输出编码 ── // 安全:Vue 模板默认编码 // // ── Python/Django 模板 ── // Django 模板自动对变量编码 // 安全: {{ user_input }} // 危险: {{ user_input|safe }} 或 {% autoescape off %}

5.4 CSRF 防御

跨站请求伪造(CSRF)防御是现代 Web 框架的标准配置:

# ── Django CSRF 配置 ── # settings.py MIDDLEWARE = [ 'django.middleware.csrf.CsrfViewMiddleware', # 启用 CSRF 中间件 # ... ] # 模板中使用 CSRF token #
# {% csrf_token %} # #
# AJAX 请求携带 CSRF token # const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value; # fetch('/api/data/', { # method: 'POST', # headers: {'X-CSRFToken': csrftoken}, # body: JSON.stringify(data), # }); # ── Spring Boot CSRF 配置 ── // Java Spring Security CSRF 配置 @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler()) ) .authorizeHttpRequests(auth -> auth .requestMatchers("/api/public/**").permitAll() .anyRequest().authenticated() ); return http.build(); } } # ── Express.js CSRF 配置 ── const csrf = require('csurf'); const csrfProtection = csrf({ cookie: true }); // 对需要保护的路由启用 CSRF app.use('/api/account', csrfProtection); app.get('/api/account/csrf-token', (req, res) => { res.json({ csrfToken: req.csrfToken() }); });

5.5 输入验证与输出编码

严格的输入验证是安全编码的第一道防线:

// ── ZOD 输入验证 Schema(TypeScript)── import { z } from 'zod'; // 用户注册输入验证 const registerSchema = z.object({ username: z .string() .min(3, '用户名至少3个字符') .max(20, '用户名最多20个字符') .regex(/^[a-zA-Z0-9_]+$/, '用户名只能包含字母、数字和下划线') .transform(v => v.toLowerCase()), email: z .string() .email('邮箱格式不正确') .max(255) .transform(v => v.toLowerCase()), password: z .string() .min(8, '密码至少8个字符') .max(128) .regex(/[A-Z]/, '密码必须包含大写字母') .regex(/[a-z]/, '密码必须包含小写字母') .regex(/[0-9]/, '密码必须包含数字') .regex(/[^A-Za-z0-9]/, '密码必须包含特殊字符'), age: z .number() .int() .min(0) .max(150) .optional(), website: z .string() .url('URL格式不正确') .optional(), }); // ── Python Pydantic 验证 ── from pydantic import BaseModel, EmailStr, Field, validator import re class RegisterInput(BaseModel): username: str = Field(min_length=3, max_length=20) email: EmailStr password: str = Field(min_length=8, max_length=128) age: int | None = Field(default=None, ge=0, le=150) website: str | None = None @validator('username') def validate_username(cls, v): if not re.match(r'^[a-zA-Z0-9_]+$', v): raise ValueError('用户名只能包含字母、数字和下划线') return v.lower() @validator('password') def validate_password(cls, v): checks = [ (r'[A-Z]', '大写字母'), (r'[a-z]', '小写字母'), (r'[0-9]', '数字'), (r'[^A-Za-z0-9]', '特殊字符'), ] for pattern, name in checks: if not re.search(pattern, v): raise ValueError(f'密码必须包含{name}') return v # ── Java Bean Validation ── // 使用 Jakarta Validation API public class RegisterRequest { @NotBlank @Size(min = 3, max = 20) @Pattern(regexp = "^[a-zA-Z0-9_]+$") private String username; @NotBlank @Email @Size(max = 255) private String email; @NotBlank @Size(min = 8, max = 128) private String password; @Min(0) @Max(150) private Integer age; }

Claude Code 安全编码辅助:在编写代码时,Claude Code 会根据 CLAUDE.md 中配置的安全规则自动审查代码,标记潜在的安全缺陷,并提供安全修复建议。开发者应当将安全规则配置为不可跳过的审查步骤。

六、安全CI/CD集成

在持续集成和部署流水线中嵌入安全检查,实现自动化的安全门禁机制。安全CI/CD确保只有通过安全审查的代码才能进入生产环境。

6.1 GitHub Actions 安全扫描工作流

以下是一个完整的多阶段安全扫描工作流,集成 SAST、依赖扫描、密钥检测和容器扫描:

# .github/workflows/security-scan.yml — 完整安全扫描流水线 name: "安全审计流水线" on: push: branches: [main, develop, release/**] pull_request: branches: [main, develop] schedule: - cron: '0 8 * * 1' # 每周一早上8点全量扫描 jobs: # ── 阶段1:SAST 静态分析 ── sast-scan: name: "SAST 代码安全扫描" runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Semgrep 扫描 uses: semgrep/semgrep-action@v1 env: SEMGREP_APP_URL: https://semgrep.dev with: config: >- p/python p/javascript p/java secrets .semgrep.yml severity: ERROR,WARNING - name: Bandit Python 扫描 if: hashFiles('setup.py') || hashFiles('requirements.txt') run: | pip install bandit bandit -r src -f json -o bandit-report.json -c .bandit.yml - name: 上传 SAST 报告 uses: actions/upload-artifact@v4 with: name: sast-reports path: | semgrep-results.* bandit-report.* # ── 阶段2:依赖漏洞扫描 ── dependency-scan: name: "依赖漏洞扫描" runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Trivy 文件系统扫描 uses: aquasecurity/trivy-action@master with: scan-type: fs scan-ref: . format: sarif output: trivy-results.sarif severity: CRITICAL,HIGH exit-code: 1 # 发现 CRITICAL/HIGH 漏洞时阻断 - name: OSV-Scanner uses: google/osv-scanner-action@v1 with: scan-args: '--recursive --fail-on-any-vulnerability .' - name: 上传依赖报告 uses: actions/upload-artifact@v4 with: name: dependency-reports path: | trivy-results.* osv-results.* # ── 阶段3:密钥检测 ── secret-detection: name: "密钥与凭证检测" runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: GitLeaks 扫描 uses: gitleaks/gitleaks-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: TruffleHog 深度扫描 uses: trufflesecurity/trufflehog@v3 with: extra_args: --only-verified --fail # ── 阶段4:安全报告 ── security-report: name: "汇总安全报告" needs: [sast-scan, dependency-scan, secret-detection] if: always() # 即使前面失败也执行 runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: 下载所有报告 uses: actions/download-artifact@v4 - name: 生成汇总报告 run: | echo "# 安全扫描汇总报告" > SECURITY_REPORT.md echo "| 扫描类型 | 状态 | 发现 |" >> SECURITY_REPORT.md echo "|---|---|---|" >> SECURITY_REPORT.md echo "| SAST 扫描 | ${{ needs.sast-scan.result }} | 查看报告 |" >> SECURITY_REPORT.md echo "| 依赖扫描 | ${{ needs.dependency-scan.result }} | 查看报告 |" >> SECURITY_REPORT.md echo "| 密钥检测 | ${{ needs.secret-detection.result }} | 查看报告 |" >> SECURITY_REPORT.md - name: 上传汇总报告 uses: actions/upload-artifact@v4 with: name: security-summary path: SECURITY_REPORT.md

6.2 安全扫描门禁与阻断规则

定义安全门禁规则,在 CI/CD 层面实现自动阻断和审批流程:

# ── 安全门禁规则 ── # 阻断规则(满足任一即阻断流水线) BLOCKING_RULES: - rule: "CRITICAL 漏洞不允许进入 staging 分支" condition: trivy --severity=CRITICAL --exit-code=1 branches: [staging, release/*] - rule: "HIGH 漏洞不允许进入 production 分支" condition: trivy --severity=HIGH --exit-code=1 branches: [main, production] - rule: "密钥泄露自动阻断任何分支" condition: gitleaks detect --verbose --exit-code=1 branches: ["*"] - rule: "SAST ERROR 级别问题阻断合并" condition: semgrep --severity=ERROR --error branches: [main, develop, release/*] # ── 例外管理流程 ── # 当需要跳过某个安全规则时,需要: # 1. 创建一个 issue 说明安全例外理由 # 2. 获得安全团队的批准 # 3. 在 commit message 中添加安全例外标记: # SECURITY_EXCEPTION: # 4. 有效期为 7 天,到期自动关闭

6.3 SARIF 报告集成

SARIF 格式是安全工具的通用输出格式,可以集成到 GitHub Security Tab 中集中管理:

# ── 将安全报告转为 SARIF 格式 ── # 上传到 GitHub Security Tab - name: Upload Semgrep SARIF uses: github/codeql-action/upload-sarif@v3 with: sarif_file: semgrep-results.sarif category: semgrep - name: Upload Trivy SARIF uses: github/codeql-action/upload-sarif@v3 with: sarif_file: trivy-results.sarif category: trivy - name: Upload CodeQL SARIF uses: github/codeql-action/upload-sarif@v3 with: sarif_file: codeql-results.sarif category: codeql # ── 自定义 SARIF 生成脚本 ── import json import datetime def generate_sarif_report(findings, tool_name, tool_version): """生成符合 SARIF 规范的安全报告""" sarif = { "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "version": "2.1.0", "runs": [{ "tool": { "driver": { "name": tool_name, "version": tool_version, "informationUri": f"https://github.com/{tool_name}" } }, "results": [], "artifacts": [], "columnKind": "utf16CodeUnits", }] } for i, finding in enumerate(findings): result = { "ruleId": finding.get("rule_id", f"{tool_name}-{i}"), "level": finding.get("severity", "warning").lower(), "message": {"text": finding.get("message", "")}, "locations": [{ "physicalLocation": { "artifactLocation": {"uri": finding.get("file", "")}, "region": { "startLine": finding.get("line", 1), "endLine": finding.get("end_line", finding.get("line", 1)), } } }] } sarif["runs"][0]["results"].append(result) return sarif

6.4 合规验证与审计日志

安全审计工作流需要满足合规要求(如 SOC2、ISO 27001、PCI DSS),记录完整的审计轨迹:

# ── 安全合规验证脚本 ── #!/bin/bash # compliance-check.sh — 安全合规验证 check_compliance() { local framework="$1" local report="compliance-${framework}-$(date +%Y%m%d).md" cat > "$report" << HEADER # 安全合规检查报告: $framework # 检查时间: $(date '+%Y-%m-%d %H:%M:%S') # 项目: $(git remote get-url origin) ## 检查项目概览 HEADER case "$framework" in "owasp-top10") echo "- [${CRITICAL_PASS:+✓}${CRITICAL_FAIL:+✗}] A01: 访问控制失效 - $(check_access_control)" >> "$report" echo "- [${CRITICAL_PASS:+✓}${CRITICAL_FAIL:+✗}] A02: 加密机制失效 - $(check_encryption)" >> "$report" echo "- [${CRITICAL_PASS:+✓}${CRITICAL_FAIL:+✗}] A03: 注入攻击 - $(check_injection)" >> "$report" # ... 其他检查项 ;; "pci-dss") echo "- [ ] 要求1: 防火墙配置 - $(check_firewall)" >> "$report" echo "- [ ] 要求2: 默认密码 - $(check_default_passwords)" >> "$report" echo "- [ ] 要求3: 持卡人数据保护 - $(check_cardholder_data)" >> "$report" ;; "hipaa") echo "- [ ] 管理 safeguard - $(check_admin_safeguards)" >> "$report" echo "- [ ] 技术 safeguard - $(check_tech_safeguards)" >> "$report" ;; esac echo "合规报告已生成: $report" } # ── 审计日志记录 ── audit_log() { local action="$1" local status="$2" local details="$3" local timestamp=$(date '+%Y-%m-%d %H:%M:%S') local user=$(git config user.name 2>/dev/null || echo "unknown") local commit=$(git rev-parse HEAD 2>/dev/null || echo "no-commit") echo "[$timestamp] [$user] [$commit] [$action] [$status] $details" >> .security-audit.log # 同时也输出 JSON 格式用于自动化处理 echo "{\"timestamp\":\"$timestamp\",\"user\":\"$user\",\"commit\":\"$commit\",\"action\":\"$action\",\"status\":\"$status\",\"details\":\"$details\"}" >> .security-audit.json } # 使用示例 # audit_log "SAST_SCAN" "PASS" "Semgrep scan completed with 0 errors" # audit_log "DEPENDENCY_SCAN" "FAIL" "Trivy found 2 CRITICAL vulnerabilities in lodash"

6.5 安全基线与例外管理

建立安全基线并管理例外情况,避免琐碎的规则影响开发效率:

# ── 安全基线配置文件 .security-baseline.yml ── baseline: version: "1.0.0" created: "2026-01-15" last_reviewed: "2026-05-01" # ── SAST 基线 ── sast: enabled: true tools: [semgrep, bandit] max_allowed_errors: 0 max_allowed_warnings: 10 excluded_paths: - "tests/**" - "**/migrations/**" - "**/vendor/**" # ── 依赖扫描基线 ── dependency: enabled: true tools: [trivy, osv-scanner] max_allowed_critical: 0 max_allowed_high: 2 # 允许有限的高危漏洞,需在例外列表中说明 max_allowed_medium: 10 auto_fix: true # ── 密钥检测基线 ── secrets: enabled: true tools: [gitleaks, talisman] block_on_any: true # 任何密钥检测结果都阻断提交 allowlist: - path: "test/fixtures/**" reason: "测试夹具包含模拟凭证" - path: "docs/examples/**" reason: "文档示例使用占位符凭证" # ── 安全例外申请模板 ── SECURITY_EXCEPTION_TEMPLATE: issue: title: "安全例外申请: [简要描述]" labels: ["security-exception", "security"] body: | ## 安全例外申请 **申请人:** [你的名字] **日期:** YYYY-MM-DD **到期日期:** YYYY-MM-DD (申请后7天) **规则ID:** [规则ID] **例外类型:** - [ ] 允许特定 CVE 延迟修复 - [ ] 跳过特定文件的安全扫描 - [ ] 放宽特定规则的严重性等级 **理由说明:** [详细说明为什么需要此例外] **缓解措施:** [在修复完成前的临时缓解方案] **批准人:** [安全团队负责人签名]

CI/CD 安全集成建议: 1. 开发分支只做警告级别的安全检查,不阻断开发流程;
2. staging/release 分支阻断 CRITICAL 漏洞;
3. production 分支阻断 HIGH 及以上漏洞;
4. 密钥检测在所有分支无差别阻断;
5. 安全报告自动归档到统一的仪表盘。

七、CLAUDE.md 中安全规则配置

CLAUDE.md 是 Claude Code 的项目级指令文件,可以配置安全审计规则,使 Claude 在编码过程中自动遵守安全规范。以下是一个面向安全审计的 CLAUDE.md 配置模板:

# CLAUDE.md — 安全审计项目规则 # 此文件配置 Claude Code 在项目中的安全审计行为 ## 安全审计规则 ### 编码约束 - 所有数据库查询必须使用参数化查询,禁止字符串拼接 SQL - 密码存储必须使用 bcrypt 或 Argon2 哈希,禁止明文存储 - 用户输入必须经过验证和净化,禁止直接信任用户输入 - 所有 API 端点必须实施认证和授权检查 - 敏感配置必须通过环境变量注入,禁止硬编码 - 日志不得包含密码、密钥、个人身份信息 ### 代码审查 checklist 每次审查代码时,Claude 必须检查以下安全要点: 1. 是否存在注入漏洞(SQL、命令、NoSQL) 2. 认证机制是否完善(会话管理、Token 验证) 3. 访问控制是否到位(权限校验、角色检查) 4. 敏感数据是否保护(加密存储、HTTPS传输) 5. 是否存在 XSS 漏洞(输出编码、CSP) 6. 是否存在 CSRF 漏洞(Token验证、SameSite Cookie) 7. 第三方依赖是否存在已知漏洞 8. 是否泄露了密钥或凭证 9. 错误处理是否泄露敏感信息 10. 日志记录是否合规 ### 安全扫描命令 - SAST 扫描: semgrep --config=auto --severity=ERROR,WARNING . - 依赖扫描: trivy fs --severity=CRITICAL,HIGH . - 密钥检测: gitleaks detect --verbose - 完整扫描: pre-commit run --all-files ### 阻断规则 - 检测到 SQL 注入:必须立即修复,代码不允许合并 - 检测到硬编码密钥:必须立即移除,代码不允许提交 - 检测到 CRITICAL 漏洞:必须修复后再合并 - 检测到敏感信息日志:必须清除后再提交 ### 自动修复流程 当发现安全问题时,Claude 应按以下优先级处理: 1. 立即阻止不安全代码提交 2. 提供安全的替代实现 3. 解释安全风险和攻击向量 4. 建议额外的安全加固措施

将上述规则配置到项目的 CLAUDE.md 中后,Claude Code 将在每次交互中自动遵守这些安全规则。当开发者编写不安全代码时,Claude 会主动指出问题并提供修复方案。

配置效果示例:当开发者要求 Claude "写一个用户登录接口"时,Claude 会自动包括密码哈希、SQL注入防护、会话管理、CSRF token、速率限制、安全日志等安全措施,因为 CLAUDE.md 中配置了相应的安全规则。

安全审计场景演示

以下展示了在 CLAUDE.md 规则作用下,Claude Code 如何进行安全审计:

# ── 场景:请求 Claude 审查代码 ── # 用户提问:"审查这段代码的安全性问题" # def login(username, password): # query = f"SELECT * FROM users WHERE username='{username}'" # user = db.execute(query) # if user.password == password: # return create_session(user.id) # ── Claude 的安全审计响应(受 CLAUDE.md 规则驱动)── # ⚠️ 发现以下安全问题: # 1. [CRITICAL] SQL 注入漏洞 # 行2: 使用 f-string 拼接 SQL 查询 # 修复: 使用参数化查询 # 正确写法: # query = "SELECT * FROM users WHERE username = %s" # user = db.execute(query, (username,)) # 2. [CRITICAL] 明文密码比较 # 行4: user.password == password # 修复: 使用密码哈希比较 # 正确写法: # from werkzeug.security import check_password_hash # if check_password_hash(user.password_hash, password): # 3. [HIGH] 缺少速率限制 # 登录接口应该实施速率限制防止暴力破解 # 4. [MEDIUM] 缺少日志记录 # 应记录登录成功/失败事件用于安全审计 # 5. [LOW] 密码错误信息过于具体 # 应统一返回 "用户名或密码错误",避免枚举攻击

八、核心要点总结

安全审计工作流是保障代码安全的关键防线,Claude Code 在其中扮演着多重角色:

  • SAST 集成者: 通过 Semgrep、CodeQL、Bandit 等工具实现自动化代码安全扫描,在编码阶段发现并修复漏洞
  • 依赖守护者: 利用 Dependabot、Trivy、OSV-Scanner 持续监控第三方依赖的已知漏洞
  • 密钥守门人: 通过 GitLeaks、Talisman、Secretlint 在预提交阶段阻断凭证泄露
  • 最佳实践教练: 基于 OWASP Top 10 指导安全编码,确保输入验证、输出编码、SQL注入防护等
  • 流水线卫士: 在 CI/CD 中嵌入多层安全门禁,自动阻断不安全代码进入生产环境
  • 规则执行者: 通过 CLAUDE.md 配置安全规则,使 AI 辅助编码内建安全意识

安全审计工作流全景图

阶段本地开发预提交CI/CD发布前
SASTIDE 实时检查pre-commit 运行GitHub Actions全量扫描
依赖npm auditlockfile 检查Trivy + OSVSBOM 生成
密钥GitLeaks 扫描Talisman 钩子Secretlint 阻断历史扫描
OWASP代码审查lint 规则SARIF 报告渗透测试
CI/CD钩子链门禁阻断部署审批
CLAUDE.md实时指导规则约束配置同步策略对齐

工作流实施建议

  1. 渐进式实施: 先实施密钥检测(最容易落地、效果最显著),再逐步引入 SAST 和依赖扫描
  2. 定制化规则: 根据项目技术栈定制安全规则,避免过多误报降低团队信任度
  3. 量化指标: 建立安全质量指标(如修复时长、漏洞发现率、阻断次数),持续跟踪改进
  4. 团队培训: 定期进行安全编码培训,让团队成员理解每项规则背后的安全原理
  5. 定期回顾: 每月回顾安全报告,优化规则配置,关闭不再适用的例外
  6. 自动化优先: 能自动化的安全检查必须自动化,减少人工审查的负担

"安全不是一个功能,也不是一个阶段,而是一个过程。真正的安全来自于将安全意识和检查融入开发的每一个环节,而不是依赖发布前的安全检查。"

本学习笔记为本人学习资料,不得转载

本文系统讲解了基于 Claude Code 的安全审计工作流,涵盖代码安全扫描、依赖漏洞扫描、密钥凭证检测、安全最佳实践、CI/CD集成和规则配置六大领域。

生成日期:2026年5月8日 | 字数:约3500字 | 代码示例:25+