安全审计清单
在对任何系统投产前或重大变更后运行这些检查。
开始之前
清单本身是散文格式,不需要额外配置。scripts/下的三个扫描器使用Python编写,因此运行它们需要你的机器上已安装 Python 3(python3 --version)。如果没有,你仍然可以手动完成清单;只是无法获得自动化的密钥扫描、标头检查和IaC读取功能。
1. 隐私与数据治理
- 若应用收集、存储或处理任何用户数据,则存在隐私政策。将其链接在页脚和注册流程中。
- 了解用户数据的存储位置:记录主数据库、缓存、日志、备份和第三方服务。检查数据驻留要求(GDPR、CCPA)。
- 数据最小化:仅收集所需数据。删除或匿名化未使用的数据。
2. 密钥与密钥卫生
- .env 值未泄露:扫描整个代码库中的硬编码密钥。
- 切勿在前端代码中暴露 API 密钥:JS 捆绑包中无密钥,公共环境前缀(
REACT_APP_、NEXT_PUBLIC_、VITE_)中无敏感值。 - 将密钥移至服务器端或代理之后:所有需要密钥的第三方 API 调用必须经过后端端点。
- 从日志中移除密钥:在日志和错误报告中搜索密钥、令牌和密码。在输出前进行屏蔽或脱敏处理。
- 立即轮换泄露的凭据(如果发现任何泄露)。
快速扫描命令:
# 运行捆绑的密钥扫描器
python3 scripts/scan_secrets.py .
# 手动 ripgrep 模式
grep -rE '(api[_-]?key|secret|token|password)\s*[:=]\s*["\047][a-zA-Z0-9_\-]{16,}' --include='*.{js,ts,py,go,rb,php,java,json,yaml,yml,env,sh,tf,hcl}' .
grep -rE 'AKIA[0-9A-Z]{16}' . # AWS 密钥
grep -rE 'ghp_[a-zA-Z0-9]{36}' . # GitHub 令牌
grep -rE 'sk-[a-zA-Z0-9]{48}' . # OpenAI 密钥
3. 安全标头
-
Content-Security-Policy限制脚本来源并尽可能阻止内联执行。 -
X-Frame-Options或frame-ancestors防止点击劫持。 -
Strict-Transport-Security强制使用 HTTPS。 - 存在
X-Content-Type-Options: nosniff。 -
Referrer-Policy限制来源泄露。
检查实时 URL 上的标头:
python3 scripts/check_headers.py https://your-app.com
4. OWASP Top 10 基础
| # | 风险 | 检查内容 |
|---|---|---|
| A01 | 破坏的访问控制 | 每个端点都检查身份验证和授权。无 IDOR 漏洞。 |
| A02 | 加密失败 | 密码使用 bcrypt/Argon2 进行哈希处理。强制使用 TLS 1.2+。URL 中无敏感数据。 |
| A03 | 注入 | SQL 使用参数化语句。查询中未对原始字符串进行拼接。 |
| A04 | 不安全设计 | 对身份验证和敏感操作设置速率限制。业务逻辑具有滥用检查。 |
| A05 | 安全配置错误 | 移除默认凭据。生产环境关闭调试模式。错误消息不泄露堆栈跟踪。 |
| A06 | 易受攻击的组件 | 依赖审计:npm audit、pip-audit、cargo audit、snyk test。 |
| A07 | 身份验证失败 | 会话令牌随机且在权限变更时轮换。对敏感账户启用 MFA。 |
| A08 | 数据完整性 | 存在锁定文件,尽可能进行签名提交。 |
| A09 | 日志记录失败 | 安全事件不包含密钥地记录日志。 |
| A10 | SSRF | 服务端请求使用白名单。用户控制的 URL 不会访问内部服务。 |
5. 输入验证与注入
- SQL 注入:所有查询使用 ORM 参数或预编译语句。
- XSS:用户输出进行 HTML 转义。审计
dangerouslySetInnerHTML及类似的绕过方式。 - 命令注入:不存在使用用户输入的
exec()、system()或eval()。 - 路径遍历:文件路径经过清理并限制在白名单目录内。
- NoSQL 注入:MongoDB 查询使用参数化对象。
6. API 安全
- 检查 API 响应中的敏感数据:无内部 ID、密码哈希、令牌或不必要的 PII。
- 对所有非公共端点进行身份验证:无开放的管理或调试路由。
- 在有人烧掉你的 API 账单之前设置速率限制:对昂贵或身份验证端点设置每 IP 和每用户的速率限制。返回
429并带上Retry-After。 - CORS 设置严格:
Access-Control-Allow-Origin不是*。对状态变更方法要求预检。
7. 身份验证与会话
- 密码策略:最少 8 个字符,无阻止口令短语的最大长度限制。
- 暴力破解防护:登录失败后指数级退避或使用 CAPTCHA。
- 会话管理:使用 secure、httpOnly、SameSite cookie。JWT 具有短有效期和刷新轮换。
- 密码重置:令牌一次性使用、随机且快速过期。
8. 云提供商安全
适用于 AWS、GCP、Azure 及任何其他云平台。
8.1 身份与访问管理 (IAM)
- 不存在根账户访问密钥。已启用根账户 MFA。
- 最小权限原则:每个角色、用户和服务账户仅拥有所需的最低权限。除非绝对必要,否则无通配符(
*)操作或资源。 - 用户无长期访问密钥。优先使用具有临时凭据的 IAM 角色(STS、实例配置文件、工作负载身份)。
- 对所有人类用户强制使用 MFA,尤其是管理员和计费访问权限。
- 移除不活跃身份:删除或禁用超过 90 天未使用的用户、角色和服务账户。
- 跨账户访问使用带有外部 ID 的显式角色假设(如适用)。不信任包含
Principal: *的策略。
8.2 存储 (S3 / GCS / Azure Blob)
- 无公共存储桶/容器,除非有意托管公共静态资源。在账户级别阻止公共访问。
- 启用静态加密(AES-256 或 KMS)。无未加密的存储卷或快照。
- 强制传输中加密(仅 HTTPS/TLS)。不允许
http。 - 生命周期策略删除或转换旧数据。对关键存储桶启用版本控制。
- 存储桶策略不授予
Principal: *或AllUsers。通过 IAM 角色(而非硬编码密钥)进行访问。 - 启用日志记录以记录访问日志和对象级事件(S3 服务器访问日志、CloudTrail 数据事件)。
8.3 计算 (EC2 / GCE / Azure VM / Lambda / Cloud Run)
- 无默认安全组允许 0.0.0.0/0 访问敏感端口(22、3389、3306、5432、6379、27017)。
- 使用 SSM / Session Manager 代替直接 SSH(如可能)。无端口 22 对互联网开放。
- 在 AWS EC2 上要求使用 IMDSv2(禁用 IMDSv1)。
- 实例元数据不暴露给容器或不受信任的代码。
- 函数运行时使用最小权限。Lambda/GCP Cloud Functions 不以内管理角色运行。
- 函数环境变量不包含明文密钥。使用密钥管理器(AWS Secrets Manager、GCP Secret Manager、Azure Key Vault)。
8.4 数据库与缓存
- 无公共访问:数据库位于私有子网或 VPC 中。安全组中无
0.0.0.0/0。 - 启用静态加密和传输中加密。
- 启用自动备份并支持时间点恢复。
- 强身份验证:无默认密码。尽可能使用 IAM 数据库身份验证或 TLS 客户端证书。
- 启用审计日志以记录连接和架构更改。
8.5 网络
- VPC / 网络分段:生产、预发布和开发环境位于不同的网络或至少不同的子网中。
- 安全组 / 防火墙默认为拒绝规则。仅开放所需端口。
- 无过度宽松的 CIDR:除非涉及面向公众的负载均衡器上的 HTTPS (443),否则避免使用
0.0.0.0/0。 - 为数据库、缓存和内部服务设置私有子网。使用 NAT 网关或 VPC 端点进行出站互联网访问。
- 启用 DDoS 保护(如适用:AWS Shield、Cloud Armor、Azure DDoS Protection)。
- DNS / 域名:如果注册商支持,启用 DNSSEC。无指向已过期 IP 或已删除资源的悬空 DNS 记录(子域名劫持风险)。
8.6 日志记录、监控与告警
- CloudTrail / 审计日志 / 活动日志在所有区域和服务中启用。
- 日志完整性:日志不可变或存储在单独的具有写入一次权限的账户中。
- 不记录敏感数据:云日志不包含密码、令牌或 PII。
- 配置告警以监控根登录、IAM 策略更改、公共存储桶创建、安全组更改和失败的身份验证峰值。
- 日志留存满足合规要求(通常为 1 年)。
9. 容器与编排安全
9.1 Docker / 容器镜像
- 镜像中无密钥:扫描 Dockerfile 和层以查找
.env、config.json或硬编码凭据。 - 最小基础镜像:尽可能使用 distroless、Alpine 或 scratch 替代完整的 Ubuntu/Debian。
- 不以 root 运行:Dockerfile 将
USER设置为非 root UID/GID。 - 镜像扫描:在镜像仓库(ECR、GCR、ACR、Docker Hub)中启用漏洞扫描,并在 CI 中阻止关键 CVE。
- 不可变标签:生产环境中不使用
latest。固定到摘要或特定 semver。 - 多阶段构建:构建工件和开发依赖不会出现在最终镜像中。
9.2 Kubernetes
- RBAC:最小权限角色和角色绑定。服务账户无 cluster-admin 权限。
- 不为不需要的 Pod 挂载默认服务账户令牌(
automountServiceAccountToken: false)。 - 网络策略:默认拒绝入口/出口,然后显式允许所需流量。
- Pod 安全标准:强制使用
restricted或baseline配置文件。无特权容器、无 hostPath、无 hostNetwork。 - 密钥加密:启用 etcd 静态加密。Git 中无明文密钥。
- 容器运行时安全:应用 seccomp、AppArmor 或 SELinux 配置文件。
- 准入控制器:使用 OPA/Gatekeeper 或 Kyverno 强制策略(无 latest 标签、必需标签、资源限制)。
- 资源限制:每个 Pod 具有 CPU 和内存限制,以防止通过资源耗尽导致的 DoS 攻击。
10. 基础设施即代码 (IaC)
- Terraform / CloudFormation / Pulumi / CDK 中无密钥:状态文件不包含明文密码或密钥。远程状态已加密并受访问控制。
- Terraform 状态后端安全:使用 SSE-KMS 的 S3、DynamoDB 锁定,且无公共读取访问。
- IaC 扫描:在合并前对 Terraform/CloudFormation 运行
checkov、tfsec或terrascan。 - 漂移检测:定期扫描检测与 IaC 偏离的手动控制台更改。
- 模块版本固定:不从分支或未版本化源拉取模块。
快速 IaC 扫描:
python3 scripts/scan_iac.py .
# 若已安装,也可使用专用工具:
checkov -d . --framework terraform,cloudformation,dockerfile
# tfsec .
11. CI/CD 流水线安全
- 流水线配置中无密钥:在
.github/workflows、.gitlab-ci.yml、Azure Pipelines 或 Jenkinsfiles 中无硬编码令牌。 - 密钥从 CI 平台的原生密钥管理器注入(GitHub Secrets、GitLab CI Variables、Azure DevOps Library)。
- 流水线权限最小化:CI 服务账户仅拥有部署所需的权限。
- 分支保护:禁止直接推送到 main/master 分支。所有更改需要 PR/MR + 代码审查。
- 签名提交或合并要求:对于敏感仓库,要求签名提交或至少经过验证的合并提交。
- 依赖扫描:SCA 工具(Snyk、Dependabot、Renovate)在每个 PR 上运行。
- SAST:静态分析(Semgrep、CodeQL、SonarQube)在每个 PR 上运行。
- 容器扫描:在部署前扫描镜像中的 CVE。
- 自托管运行器不得在没有 VPN 或 IP 白名单的情况下暴露于公共互联网。
- 流水线不运行来自复刻的不受信任代码(未经手动批准,防止 pwn 请求)。
12. 域名与 DNS 安全
- DNSSEC 在注册商处启用(如果支持)。
- 无指向已过期服务的悬空 CNAME / A / NS 记录(子域名劫持风险)。
- 通配符证书或每个主体的证书来自受信任的 CA。生产环境中无自签名证书。
- 证书过期监控:在到期前 30 天和 7 天发出告警。
- CDN / WAF 配置合理的规则(SQLi、XSS、LFI 阻止)。在边缘启用速率限制。
审计输出
运行清单后,生成一份简洁的 Markdown 报告,包含:
- 摘要 — 每个类别的通过/失败/需要审查状态。
- 关键发现 — 任何必须在投产前修复的问题。
- 推荐修复 — 具体的代码更改、配置更新或库升级建议。
- 风险矩阵 — 每个发现的可能性 × 影响评估。
- 修复时间线 — 建议的优先级顺序和截止日期。