代码审计 (Code Audit/Review)
1. 概述
安全代码审计是SDL验证阶段的核心活动, 通过系统性地审查源代码来发现安全缺陷。与功能性代码审查不同, 安全代码审计聚焦于漏洞模式识别、安全控制验证和攻击面分析。有效的代码审计结合手动审查的深度分析能力和自动化工具的广度覆盖, 形成互补的安全检测体系。
2. 手动审查技术
2.1 审查策略
手动安全代码审查不同于逐行阅读代码。应采用有针对性的审查策略:
- 数据流追踪 (Data Flow Tracing) - 从用户输入点出发, 追踪数据流经的所有处理节点, 直到输出点或持久化点。检查每个节点是否实施了适当的安全控制
- 攻击面枚举 - 识别所有外部可达的入口点 (HTTP Endpoint, 消息队列消费者, 定时任务等), 评估每个入口点的安全防护
- 安全控制审查 - 验证认证、授权、输入验证、输出编码等安全控制的实现正确性和完整性
- 配置审查 - 检查安全相关配置 (如 CORS, CSP, Cookie 属性, TLS 设置) 是否符合安全基线
2.2 高频漏洞模式
手动审查时应重点关注以下高频漏洞模式:
- 注入类: SQL注入、命令注入、LDAP注入、XPath注入、模板注入 (SSTI)
- 认证授权类: 硬编码凭据、权限校验缺失、JWT 验证不完整 (如未校验签名算法)
- 业务逻辑类: 竞态条件 (TOCTOU)、整数溢出、不安全的直接对象引用 (IDOR)
- 加密类: 弱加密算法、ECB 模式、硬编码密钥、不安全的随机数
- 信息泄露类: 详细错误信息、调试接口未关闭、敏感数据日志记录
常见误区
安全代码审查不应沦为"找 bug"的活动。其真正价值在于评估系统整体的安全设计是否合理, 安全控制是否成体系, 而非仅仅发现个别漏洞。
3. SAST工具对比
静态应用安全测试 (SAST) 工具通过分析源代码或字节码来自动检测安全缺陷。以下是主流SAST工具的对比:
| 工具 | 类型 | 优势 | 局限 |
|---|---|---|---|
| Semgrep | 开源 | 规则编写简单 (类似 grep 的语法), 轻量快速, 支持 30+ 语言, 社区规则库丰富 | 语义分析能力有限, 跨文件追踪较弱 |
| CodeQL | 免费 (GitHub) | 强大的查询语言, 深度语义分析, 支持自定义数据流查询 | 学习曲线较陡, 需要构建数据库, 分析速度较慢 |
| Checkmarx | 商业 | 企业级功能完善, 支持增量扫描, IDE 集成好, 合规报告丰富 | 价格高, 误报率需要持续调优 |
| SonarQube | 开源/商业 | 代码质量 + 安全综合平台, CI/CD 集成成熟, 社区版可用 | 安全规则深度不如专业 SAST 工具 |
| Fortify | 商业 | 行业老牌, 语言覆盖广, 规则库全面, 合规认证多 | 价格昂贵, 扫描速度慢, 配置复杂 |
选型建议
对于初始引入 SAST 的团队, 建议从 Semgrep + SonarQube 组合起步: Semgrep 负责安全专项扫描, SonarQube 负责代码质量综合管理。随着安全成熟度提升, 可评估引入 CodeQL 进行深度分析。
4. 审查清单 (Review Checklist)
以下是安全代码审查的核心检查清单, 可作为 Pull Request 审查的安全维度补充:
4.1 输入处理
- 所有外部输入是否在服务端进行了验证?
- SQL查询是否使用参数化查询?
- HTML输出是否进行了上下文感知编码?
- 文件上传是否校验了文件类型和大小?
- 反序列化操作是否使用了白名单过滤?
4.2 认证与授权
- 是否每个 API Endpoint 都有明确的权限检查?
- 是否存在基于客户端数据的权限判断 (如隐藏字段、URL 参数)?
- 密码是否使用了适当的哈希算法存储?
- Session/Token 的生命周期管理是否合理?
4.3 数据保护
- 敏感数据是否加密存储和传输?
- 密钥和凭据是否从配置中分离 (不硬编码)?
- 日志中是否排除了敏感信息?
- 错误响应是否避免泄露内部信息?
4.4 并发与资源
- 是否存在竞态条件 (特别是余额、库存等场景)?
- 外部调用是否设置了超时和重试限制?
- 资源 (连接、文件句柄) 是否在所有路径上正确释放?
5. 常见漏洞模式详解
5.1 不安全的直接对象引用 (IDOR)
当应用程序使用用户提供的标识符 (如 ID) 直接访问后端对象, 且未验证该用户是否有权访问该对象时, 就产生了 IDOR 漏洞。这是 Web 应用中最常见也最容易被忽视的漏洞类型之一。
审查重点: 检查所有接受资源 ID 参数的接口, 确认是否在业务逻辑层校验了资源归属关系, 而非仅依赖前端隐藏或 URL 路径控制。
5.2 服务端请求伪造 (SSRF)
当应用程序根据用户提供的 URL 发起服务端请求时, 攻击者可能利用此功能访问内部服务、云元数据 API 或进行端口扫描。
审查重点: 检查所有接受 URL 参数的接口 (如 webhook 配置、图片抓取、文件导入), 确认是否实施了 URL 白名单、DNS 重绑定防护和内网地址过滤。
6. 审计流程集成
将安全代码审查融入日常开发流程的建议:
- PR级别: 每个 Pull Request 需经过至少一名具备安全审查能力的工程师审核
- Sprint级别: 每个 Sprint 末尾进行安全相关代码的集中审查
- Release级别: 重大版本发布前执行全面的安全代码审计
- 持续集成: SAST 工具集成到 CI 流水线, 每次构建自动扫描
7. 小结
安全代码审计是发现和修复安全缺陷的最后一道重要防线。通过手动审查与自动化工具的结合, 建立覆盖从PR到Release各环节的审计体系, 能够有效降低应用安全风险。关键在于将安全审查常态化, 使其成为开发流程中不可跳过的质量门禁。