integrating-dast-with-owasp-zap-in-pipeline
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseIntegrating DAST with OWASP ZAP in Pipeline
在流水线中集成OWASP ZAP实现DAST测试
When to Use
适用场景
- When testing running web applications for vulnerabilities like XSS, SQLi, CSRF, and misconfigurations
- When SAST alone is insufficient and runtime behavior testing is required
- When compliance mandates dynamic security testing of web applications before production
- When testing APIs (REST/GraphQL) for authentication, authorization, and injection flaws
- When establishing continuous DAST scanning in staging environments before production deployment
Do not use for scanning source code (use SAST), for scanning dependencies (use SCA), or for infrastructure configuration scanning (use IaC scanning tools).
- 针对运行中的Web应用测试XSS、SQL注入(SQLi)、CSRF及配置错误等漏洞时
- 仅使用静态应用安全测试(SAST)不足以满足需求,需要测试运行时行为时
- 合规要求在生产部署前对Web应用进行动态安全测试时
- 针对REST/GraphQL API测试认证、授权及注入缺陷时
- 在生产部署前,在预发布环境中建立持续DAST扫描机制时
不适用场景:扫描源代码(请使用SAST)、扫描依赖项(请使用SCA)或扫描基础设施配置(请使用IaC扫描工具)。
Prerequisites
前提条件
- OWASP ZAP Docker image or installed locally (zaproxy/zap-stable or zaproxy/action-*)
- Running target application accessible from the CI/CD runner (staging URL or Docker service)
- ZAP scan rules configuration (optional, for tuning)
- OpenAPI/Swagger specification for API scanning (optional)
- OWASP ZAP Docker镜像或本地安装版本(zaproxy/zap-stable或zaproxy/action-*)
- CI/CD运行器可访问的运行中目标应用(预发布URL或Docker服务)
- ZAP扫描规则配置(可选,用于自定义扫描)
- API扫描用的OpenAPI/Swagger规范(可选)
Workflow
工作流程
Step 1: Configure ZAP Baseline Scan in GitHub Actions
步骤1:在GitHub Actions中配置ZAP基线扫描
yaml
undefinedyaml
undefined.github/workflows/dast-scan.yml
.github/workflows/dast-scan.yml
name: DAST Security Scan
on:
deployment_status:
workflow_dispatch:
inputs:
target_url:
description: 'Target URL to scan'
required: true
jobs:
zap-baseline:
name: ZAP Baseline Scan
runs-on: ubuntu-latest
services:
webapp:
image: ${{ github.repository }}:${{ github.sha }}
ports:
- 8080:8080
options: --health-cmd="curl -f http://localhost:8080/health" --health-interval=10s --health-timeout=5s --health-retries=5
steps:
- uses: actions/checkout@v4
- name: ZAP Baseline Scan
uses: zaproxy/action-baseline@v0.12.0
with:
target: 'http://webapp:8080'
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a -j'
allow_issue_writing: false
- name: Upload ZAP Report
if: always()
uses: actions/upload-artifact@v4
with:
name: zap-baseline-report
path: report_html.htmlundefinedname: DAST Security Scan
on:
deployment_status:
workflow_dispatch:
inputs:
target_url:
description: 'Target URL to scan'
required: true
jobs:
zap-baseline:
name: ZAP Baseline Scan
runs-on: ubuntu-latest
services:
webapp:
image: ${{ github.repository }}:${{ github.sha }}
ports:
- 8080:8080
options: --health-cmd="curl -f http://localhost:8080/health" --health-interval=10s --health-timeout=5s --health-retries=5
steps:
- uses: actions/checkout@v4
- name: ZAP Baseline Scan
uses: zaproxy/action-baseline@v0.12.0
with:
target: 'http://webapp:8080'
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a -j'
allow_issue_writing: false
- name: Upload ZAP Report
if: always()
uses: actions/upload-artifact@v4
with:
name: zap-baseline-report
path: report_html.htmlundefinedStep 2: Configure ZAP Full Scan for Comprehensive Testing
步骤2:配置ZAP全面扫描以开展深度测试
yaml
zap-full-scan:
name: ZAP Full Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: ZAP Full Scan
uses: zaproxy/action-full-scan@v0.12.0
with:
target: ${{ github.event.inputs.target_url || 'https://staging.example.com' }}
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a -j -T 60'
- name: Upload Reports
if: always()
uses: actions/upload-artifact@v4
with:
name: zap-full-report
path: |
report_html.html
report_json.jsonyaml
zap-full-scan:
name: ZAP Full Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: ZAP Full Scan
uses: zaproxy/action-full-scan@v0.12.0
with:
target: ${{ github.event.inputs.target_url || 'https://staging.example.com' }}
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a -j -T 60'
- name: Upload Reports
if: always()
uses: actions/upload-artifact@v4
with:
name: zap-full-report
path: |
report_html.html
report_json.jsonStep 3: Configure API Scan with OpenAPI Specification
步骤3:结合OpenAPI规范配置API扫描
yaml
zap-api-scan:
name: ZAP API Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: ZAP API Scan
uses: zaproxy/action-api-scan@v0.12.0
with:
target: 'https://staging.example.com/api/openapi.json'
format: openapi
rules_file_name: '.zap/api-rules.tsv'
cmd_options: '-a -j'yaml
zap-api-scan:
name: ZAP API Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: ZAP API Scan
uses: zaproxy/action-api-scan@v0.12.0
with:
target: 'https://staging.example.com/api/openapi.json'
format: openapi
rules_file_name: '.zap/api-rules.tsv'
cmd_options: '-a -j'Step 4: Configure ZAP Scan Rules
步骤4:配置ZAP扫描规则
tsv
undefinedtsv
undefined.zap/rules.tsv
.zap/rules.tsv
Rule ID Action (IGNORE/WARN/FAIL) Description
Rule ID Action (IGNORE/WARN/FAIL) Description
10003 IGNORE # Vulnerable JS Library (handled by SCA)
10015 WARN # Incomplete or No Cache-control Header
10021 FAIL # X-Content-Type-Options Missing
10035 FAIL # Strict-Transport-Security Missing
10038 FAIL # Content Security Policy Missing
10098 IGNORE # Cross-Domain Misconfiguration (CDN)
40012 FAIL # Cross Site Scripting (Reflected)
40014 FAIL # Cross Site Scripting (Persistent)
40018 FAIL # SQL Injection
40019 FAIL # SQL Injection (MySQL)
40032 FAIL # .htaccess Information Leak
90033 FAIL # Loosely Scoped Cookie
undefined10003 IGNORE # Vulnerable JS Library (handled by SCA)
10015 WARN # Incomplete or No Cache-control Header
10021 FAIL # X-Content-Type-Options Missing
10035 FAIL # Strict-Transport-Security Missing
10038 FAIL # Content Security Policy Missing
10098 IGNORE # Cross-Domain Misconfiguration (CDN)
40012 FAIL # Cross Site Scripting (Reflected)
40014 FAIL # Cross Site Scripting (Persistent)
40018 FAIL # SQL Injection
40019 FAIL # SQL Injection (MySQL)
40032 FAIL # .htaccess Information Leak
90033 FAIL # Loosely Scoped Cookie
undefinedStep 5: Run ZAP with Docker Compose for Local Testing
步骤5:使用Docker Compose运行ZAP进行本地测试
yaml
undefinedyaml
undefineddocker-compose.zap.yml
docker-compose.zap.yml
version: '3.8'
services:
webapp:
build: .
ports:
- "8080:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
retries: 5
zap:
image: zaproxy/zap-stable:latest
depends_on:
webapp:
condition: service_healthy
command: >
zap-baseline.py
-t http://webapp:8080
-r /zap/wrk/report.html
-J /zap/wrk/report.json
-c /zap/wrk/rules.tsv
-I
volumes:
- ./zap-reports:/zap/wrk
- ./.zap/rules.tsv:/zap/wrk/rules.tsv
undefinedversion: '3.8'
services:
webapp:
build: .
ports:
- "8080:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
retries: 5
zap:
image: zaproxy/zap-stable:latest
depends_on:
webapp:
condition: service_healthy
command: >
zap-baseline.py
-t http://webapp:8080
-r /zap/wrk/report.html
-J /zap/wrk/report.json
-c /zap/wrk/rules.tsv
-I
volumes:
- ./zap-reports:/zap/wrk
- ./.zap/rules.tsv:/zap/wrk/rules.tsv
undefinedKey Concepts
核心概念
| Term | Definition |
|---|---|
| DAST | Dynamic Application Security Testing — tests running applications by sending requests and analyzing responses |
| Baseline Scan | Quick passive scan that spiders the application without active attacks, suitable for CI/CD |
| Full Scan | Active scan including attack payloads for XSS, SQLi, and other injection vulnerabilities |
| API Scan | Targeted scan using OpenAPI/Swagger specs to test all documented API endpoints |
| Spider | ZAP's crawler that discovers application pages and endpoints by following links |
| Active Scan | Phase where ZAP sends attack payloads to discovered endpoints to find exploitable vulnerabilities |
| Passive Scan | Analysis of HTTP responses for security headers, cookies, and information disclosure without sending attacks |
| Scan Policy | Configuration defining which attack types to enable and their intensity levels |
| 术语 | 定义 |
|---|---|
| DAST | 动态应用安全测试——通过发送请求并分析响应来测试运行中的应用 |
| Baseline Scan | 快速被动扫描,会爬取应用但不发起主动攻击,适合CI/CD场景 |
| Full Scan | 主动扫描,包含针对XSS、SQL注入及其他注入漏洞的攻击载荷 |
| API Scan | 基于OpenAPI/Swagger规范的定向扫描,用于测试所有已文档化的API端点 |
| Spider | ZAP的爬虫工具,通过跟随链接发现应用页面和端点 |
| Active Scan | ZAP向已发现的端点发送攻击载荷以查找可利用漏洞的阶段 |
| Passive Scan | 分析HTTP响应中的安全头、Cookie和信息泄露情况,不发起攻击 |
| Scan Policy | 定义启用哪些攻击类型及其强度级别的配置 |
Tools & Systems
工具与系统
- OWASP ZAP: Open-source web application security scanner for DAST testing
- zaproxy/action-baseline: GitHub Action for ZAP passive baseline scanning
- zaproxy/action-full-scan: GitHub Action for ZAP active full scanning
- zaproxy/action-api-scan: GitHub Action for API-focused scanning with OpenAPI support
- Nuclei: Alternative vulnerability scanner with template-based detection for CI/CD integration
- OWASP ZAP: 用于DAST测试的开源Web应用安全扫描器
- zaproxy/action-baseline: 用于ZAP被动基线扫描的GitHub Action
- zaproxy/action-full-scan: 用于ZAP主动全面扫描的GitHub Action
- zaproxy/action-api-scan: 支持OpenAPI的API聚焦扫描GitHub Action
- Nuclei: 基于模板检测的替代漏洞扫描器,适合CI/CD集成
Common Scenarios
常见场景
Scenario: Integrating DAST into a Staging Deployment Pipeline
场景:将DAST集成到预发布部署流水线
Context: A team deploys to staging before production and needs automated DAST scanning between stages to catch runtime vulnerabilities.
Approach:
- Add a DAST job in the pipeline that triggers after successful staging deployment
- Run ZAP baseline scan first for quick passive feedback (2-5 minutes)
- Follow with a targeted API scan using the application's OpenAPI specification
- Configure rules.tsv to FAIL on critical findings (XSS, SQLi) and WARN on headers/cookies
- Upload ZAP reports as pipeline artifacts for review
- Block production deployment if any FAIL-level findings are detected
- Schedule weekly full scans against staging for deeper coverage
Pitfalls: ZAP full scans can take 30+ minutes and may overwhelm staging servers with attack traffic. Use baseline scans in CI and full scans on schedule. Running DAST against production without coordination can trigger WAF blocks and incident alerts.
背景:团队在生产部署前会先部署到预发布环境,需要在阶段之间加入自动化DAST扫描以发现运行时漏洞。
实施方法:
- 在流水线中添加DAST任务,成功部署到预发布环境后触发
- 先运行ZAP基线扫描以快速获得被动反馈(2-5分钟)
- 随后使用应用的OpenAPI规范进行定向API扫描
- 配置rules.tsv,将严重检测结果(如XSS、SQL注入)设为FAIL,将头信息/Cookie相关问题设为WARN
- 将ZAP报告上传为流水线工件以供审核
- 若存在任何FAIL级别的检测结果,阻止生产部署
- 每周针对预发布环境安排一次全面扫描以获得更深度的覆盖
注意事项:ZAP全面扫描可能需要30分钟以上,且攻击流量可能会压垮预发布服务器。建议在CI中使用基线扫描,全面扫描则按计划执行。未经协调直接在生产环境运行DAST可能会触发WAF拦截和事件告警。
Output Format
输出格式
ZAP DAST Scan Report
======================
Target: https://staging.example.com
Scan Type: Baseline + API
Date: 2026-02-23
Duration: 4m 32s
FINDINGS:
FAIL: 3
WARN: 7
INFO: 12
PASS: 45
FAILING ALERTS:
[HIGH] 40012 - Cross Site Scripting (Reflected)
URL: https://staging.example.com/search?q=<script>
Method: GET
Evidence: <script>alert(1)</script>
[MEDIUM] 10021 - X-Content-Type-Options Missing
URL: https://staging.example.com/api/v1/*
Evidence: Response header missing
[MEDIUM] 10035 - Strict-Transport-Security Missing
URL: https://staging.example.com/
Evidence: HSTS header not present
QUALITY GATE: FAILED (1 HIGH, 2 MEDIUM findings)ZAP DAST Scan Report
======================
Target: https://staging.example.com
Scan Type: Baseline + API
Date: 2026-02-23
Duration: 4m 32s
FINDINGS:
FAIL: 3
WARN: 7
INFO: 12
PASS: 45
FAILING ALERTS:
[HIGH] 40012 - Cross Site Scripting (Reflected)
URL: https://staging.example.com/search?q=<script>
Method: GET
Evidence: <script>alert(1)</script>
[MEDIUM] 10021 - X-Content-Type-Options Missing
URL: https://staging.example.com/api/v1/*
Evidence: Response header missing
[MEDIUM] 10035 - Strict-Transport-Security Missing
URL: https://staging.example.com/
Evidence: HSTS header not present
QUALITY GATE: FAILED (1 HIGH, 2 MEDIUM findings)