Dynamic Testing & Runtime Security
OWASP ZAP Automation in Pipelines
3 min read
OWASP ZAP (Zed Attack Proxy) is the world's most popular free DAST tool. Here's how to integrate it into your CI/CD pipeline.
ZAP Scan Types
| Scan Type | Duration | Coverage | Use Case |
|---|---|---|---|
| Baseline | 1-5 min | Low | PR checks, quick validation |
| Full | 30-120 min | High | Nightly scans, pre-release |
| API | 5-30 min | API only | REST/GraphQL testing |
| Ajax Spider | 15-60 min | SPAs | React, Vue, Angular apps |
GitHub Actions Integration
Baseline Scan (Fast)
# .github/workflows/dast-baseline.yml
name: DAST Baseline Scan
on:
pull_request:
branches: [main]
jobs:
zap-baseline:
runs-on: ubuntu-latest
steps:
- name: Deploy to staging
run: |
# Your deployment script
echo "Deploying to staging..."
- name: ZAP Baseline Scan
uses: zaproxy/action-baseline@v0.10.0
with:
target: 'https://staging.example.com'
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a' # Include alpha rules
- name: Upload ZAP Report
uses: actions/upload-artifact@v4
with:
name: zap-report
path: report_html.html
Full Scan (Comprehensive)
# .github/workflows/dast-full.yml
name: DAST Full Scan
on:
schedule:
- cron: '0 2 * * *' # 2 AM daily
jobs:
zap-full:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: ZAP Full Scan
uses: zaproxy/action-full-scan@v0.9.0
with:
target: 'https://staging.example.com'
rules_file_name: '.zap/rules.tsv'
cmd_options: >
-j # Use Ajax spider
-m 5 # Spider timeout 5 min
- name: Upload Results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'zap-results.sarif'
Configuring ZAP Rules
Create custom rules to tune scan behavior:
# .zap/rules.tsv
# ID Action Name
10021 IGNORE X-Content-Type-Options Header Missing
10038 WARN Content Security Policy (CSP) Header Not Set
40012 FAIL Cross Site Scripting (Reflected)
40014 FAIL Cross Site Scripting (Persistent)
90022 FAIL Application Error Disclosure
Actions:
IGNORE: Don't report (false positive)WARN: Report but don't fail pipelineFAIL: Report and fail pipeline
Authenticated Scanning
Most apps require login. Use ZAP's authentication options:
Option 1: Context File
# .zap/context.xml
<context>
<name>MyApp</name>
<authentication>
<type>formBasedAuthentication</type>
<loginUrl>https://app.example.com/login</loginUrl>
<loginRequestBody>username={%username%}&password={%password%}</loginRequestBody>
</authentication>
<users>
<user>
<name>test-user</name>
<credentials>
<username>testuser</username>
<password>${ZAP_AUTH_PASSWORD}</password>
</credentials>
</user>
</users>
</context>
# GitHub Actions with auth
- name: ZAP Full Scan
uses: zaproxy/action-full-scan@v0.9.0
with:
target: 'https://staging.example.com'
docker_name: 'ghcr.io/zaproxy/zaproxy:stable'
env:
ZAP_AUTH_PASSWORD: ${{ secrets.ZAP_AUTH_PASSWORD }}
Option 2: Authorization Header
# For API/JWT authentication
- name: ZAP API Scan
uses: zaproxy/action-api-scan@v0.6.0
with:
target: 'https://api.example.com/openapi.json'
cmd_options: >
-z "replacer.full_list(0).description=auth"
-z "replacer.full_list(0).enabled=true"
-z "replacer.full_list(0).matchtype=REQ_HEADER"
-z "replacer.full_list(0).matchstr=Authorization"
-z "replacer.full_list(0).replacement=Bearer ${{ secrets.API_TOKEN }}"
Handling Results
Fail on Critical Findings
- name: Check ZAP Results
run: |
if grep -q "FAIL-NEW" zap-results.json; then
echo "New vulnerabilities found!"
exit 1
fi
Create GitHub Issues
- name: Create Issue on Failure
if: failure()
uses: actions/github-script@v7
with:
script: |
github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: 'DAST Scan Found Vulnerabilities',
body: 'Check the ZAP report in the workflow artifacts.',
labels: ['security', 'dast']
})
Performance Tips
| Optimization | How |
|---|---|
| Limit spider depth | --spider.maxDepth=5 |
| Exclude static assets | `--exclude='.*.(css |
| Use baseline for PRs | Faster, common vulns only |
| Run full scans nightly | Off peak hours |
| Cache ZAP Docker image | Use docker pull step |
Next, we'll explore API security testing with Nuclei. :::