软件安全问题越早发现,修复成本越低。SAST、DAST 和 SCA 是现代应用安全测试的三大利器,分别从不同维度发现安全缺陷。本文系统讲解三种技术的原理、工具选型与 CI/CD 集成实践。
1. 安全测试方法对比
代码安全测试方法
│
┌─────────┼─────────┐
│ │ │
SAST DAST SCA
(白盒) (黑盒) (成分)
│ │ │
▼ ▼ ▼
源代码 运行应用 依赖库
分析 测试 漏洞
| 维度 | SAST | DAST | SCA |
|---|---|---|---|
| 测试阶段 | 开发/构建 | 测试/运行时 | 构建/部署 |
| 是否需要运行 | 否 | 是 | 否 |
| 发现漏洞类型 | 代码级(注入、逻辑缺陷) | 运行时(配置错误、认证绕过) | 依赖漏洞(CVE) |
| 误报率 | 较高 | 较低 | 低 |
| 覆盖范围 | 全部代码 | 可访问接口 | 全部依赖 |
| 修复成本 | 低(开发阶段) | 中 | 低 |
2. SAST 静态应用安全测试
2.1 工作原理
源代码 ──► 词法/语法分析 ──► AST(抽象语法树)──► 控制流/数据流分析
│
▼
安全规则引擎
│
▼
┌─────────────┴─────────────┐
│ 漏洞模式匹配(污点分析) │
│ - 不可信输入 → 危险函数 │
│ - 敏感数据泄露 │
│ - 加密误用 │
└───────────────────────────┘
污点分析(Taint Analysis):跟踪用户输入(污点源)是否到达危险函数(污点汇聚点)。
2.2 SonarQube
# docker-compose.yml
services:
sonarqube:
image: sonarqube:community
ports:
- "9000:9000"
environment:
- SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
# Maven 项目扫描
mvn sonar:sonar \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.login=sqp_xxx
SonarQube 规则集:
- SonarWay(默认 500+ 规则)
- OWASP Top 10
- CWE(Common Weakness Enumeration)
- SANS Top 25
2.3 Semgrep(轻量级、规则灵活)
# .semgrep.yml
rules:
- id: no-raw-sql
pattern: |
String $SQL = $X + $Y;
$STMT.executeQuery($SQL);
message: "禁止字符串拼接 SQL,请使用参数化查询"
languages: [java]
severity: ERROR
- id: no-weak-hash
pattern-either:
- pattern: MessageDigest.getInstance("MD5")
- pattern: MessageDigest.getInstance("SHA1")
message: "使用 MD5/SHA1 不安全,请使用 SHA-256+"
languages: [java]
severity: WARNING
# 运行扫描
semgrep --config=auto --json --output=semgrep-report.json .
# 或使用 registry 规则
semgrep --config=p/owasp-top-ten .
semgrep --config=p/javascript .
semgrep --config=p/ci .
2.4 CodeQL(GitHub 原生)
# .github/workflows/codeql.yml
name: "CodeQL"
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v3
with:
languages: java
queries: security-extended,security-and-quality
- uses: github/codeql-action/analyze@v3
CodeQL 特点:
- 将代码编译为关系数据库(CodeQL DB)
- 使用类 SQL 的 QL 语言编写查询
- GitHub Security 面板集成
- 支持数据流分析(跨函数追踪)
3. DAST 动态应用安全测试
3.1 工作原理
爬虫 ──► 发现 URL/接口 ──► 攻击载荷注入 ──► 分析响应
│ │ │
│ ▼ ▼
│ SQL/XSS/... 漏洞确认
│ 模糊测试
│
└── 认证绕过 ──► 扫描需要登录的页面
3.2 OWASP ZAP
# Docker 运行
docker run -t owasp/zap2docker-stable zap-baseline.py \
-t https://target-app.com \
-r zap-report.html
# 全量扫描( longer ,更彻底 )
docker run -t owasp/zap2docker-stable zap-full-scan.py \
-t https://target-app.com \
-r zap-report.html
# 带认证的扫描
docker run -t owasp/zap2docker-stable zap-full-scan.py \
-t https://target-app.com \
--hook=/zap/auth_hook.py \
-z "auth.loginurl=https://target-app.com/login"
3.3 Burp Suite(专业版)
功能更全面但收费:
- 手动拦截与修改请求
- 自动化扫描
- Intruder(爆破工具)
- Repeater(重放请求)
4. SCA 软件成分分析
4.1 供应链风险
Your App
├── log4j-core 2.14.1 ← CVE-2021-44228 (Log4Shell, 10.0 CVSS)
├── jackson-databind 2.9.8 ← CVE-2019-14540 (反序列化)
├── lodash 4.17.15 ← CVE-2020-8203 (原型污染)
└── spring-core 5.3.15 ← CVE-2022-22965 (Spring4Shell)
4.2 Snyk
# CLI 扫描
npm install -g snyk
snyk test # 测试依赖漏洞
snyk monitor # 持续监控
snyk test --json > report.json
# 修复建议
snyk fix # 自动尝试升级修复
# Docker 镜像扫描
snyk container test myapp:latest
4.3 OWASP Dependency-Check
<!-- Maven -->
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<configuration>
<failBuildOnCVSS>7</failBuildOnCVSS>
</configuration>
</plugin>
<!-- 运行 -->
<!-- mvn org.owasp:dependency-check-maven:check -->
4.4 GitHub Dependabot
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "maven"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10
- package-ecosystem: "npm"
directory: "/frontend"
schedule:
interval: "weekly"
5. CI/CD 安全流水线集成
5.1 安全门禁设计
# .gitlab-ci.yml
stages:
- build
- test
- security
- deploy
sast:
stage: security
image: returntocorp/semgrep
script:
- semgrep --config=auto --json --output=semgrep.json .
artifacts:
reports:
sast: semgrep.json
allow_failure: false # 安全门禁:失败即阻断
sca:
stage: security
image: maven:3.9
script:
- mvn org.owasp:dependency-check-maven:check
artifacts:
reports:
dependency_scanning: target/dependency-check-report.json
allow_failure: false
dast:
stage: security
image: owasp/zap2docker-stable
script:
- zap-baseline.py -t $CI_ENVIRONMENT_URL -r dast-report.html
artifacts:
reports:
dast: dast-report.html
allow_failure: true # DAST 可能不稳定,允许失败但告警
5.2 质量门禁规则
# SonarQube Quality Gate
conditions:
- metric: vulnerabilities
operator: GT
threshold: 0 # 不允许任何安全漏洞
- metric: security_hotspots_reviewed
operator: LT
threshold: 100 # 安全热点必须全部审核
- metric: coverage
operator: LT
threshold: 80 # 测试覆盖率 > 80%
6. 工具选型建议
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 快速集成 | Semgrep | 轻量、规则灵活、速度快 |
| 全平台覆盖 | SonarQube | 多语言、规则全面、IDE 集成 |
| GitHub 项目 | CodeQL + Dependabot | 原生集成、免费 |
| 依赖监控 | Snyk | 漏洞数据库最及时、修复建议 |
| 合规要求 | Checkmarx / Veracode | 企业级报告、合规认证 |
| DAST 扫描 | OWASP ZAP(免费)/ Burp Suite(专业) | 开源/商业 |
7. 总结
安全测试工具链的最佳实践:
开发阶段 ──► SAST (Semgrep/Sonarlint IDE 插件) ← 实时反馈
│
代码提交 ──► SAST (SonarQube/CodeQL) + SCA (Dependabot) ← MR/PR 门禁
│
构建阶段 ──► SCA (Dependency-Check/Snyk) ← 阻断高危 CVE
│
测试环境 ──► DAST (ZAP) ← 运行时漏洞
│
生产环境 ──► SCA 持续监控 + 运行时安全 (RASP) ← 新 CVE 告警
安全左移(Shift Left Security)的核心是将安全测试尽可能前移到开发早期:
- IDE 实时检测 → 问题发现最早
- CI 门禁拦截 → 阻止有问题的代码合并
- 持续监控 → 响应新披露漏洞
工具链不是万能的。最终安全取决于安全编码规范、代码审查和安全文化的建设。
漏洞修复优先级与 SLAS
不是每个 CVE 都需要立刻修复。根据风险评分决定响应速度:
| CVSS 分数 | 严重等级 | 修复 SLA | 示例 |
|---|---|---|---|
| 9.0-10.0 | 严重 | 24 小时内 | Log4Shell (CVE-2021-44228) |
| 7.0-8.9 | 高危 | 7 天内 | Spring4Shell |
| 4.0-6.9 | 中危 | 30 天内 | 信息泄露 |
| 0.1-3.9 | 低危 | 90 天内 | 依赖升级 |
实际优先级还需考虑:
- 可利用性(Exploitability):有公开 POC 的漏洞需加速修复
- 资产暴露面:公网暴露的服务优先,内网低敏服务可延后
- 业务影响:支付模块的漏洞 > 内部管理后台的漏洞
零日漏洞应急响应
T+0h: 安全团队确认漏洞影响范围
T+2h: 评估临时缓解措施(WAF 规则、输入过滤)
T+4h: 部署缓解措施,阻断攻击路径
T+24h: 获取官方补丁或临时修复方案
T+48h: 完成全量修复部署
T+72h: 验证修复效果,复盘响应流程
对于无法立即升级依赖的遗留系统,可在入口层部署虚拟补丁:
- ModSecurity / Nginx WAF 规则拦截恶意 payload
- API Gateway 层增加输入校验和速率限制
安全测试的深度扩展
IAST(交互式应用安全测试)
IAST 结合 SAST 和 DAST 的优点:在应用运行时插桩,实时检测漏洞。
| 特性 | SAST | DAST | IAST |
|---|---|---|---|
| 阶段 | 构建 | 运行 | 运行 |
| 误报率 | 高 | 中 | 低 |
| 代码覆盖 | 全部 | 可达路径 | 实际执行路径 |
| 部署复杂度 | 低 | 中 | 高(需 Agent) |
IAST Agent 通过 Java -javaagent 或 Node.js require 注入,在生产环境低开销运行,适合补充 SAST 的盲区(如反射调用、动态路由)。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。