Implementing DAST in CI/CD Pipelines
Implementing DAST in CI/CD Pipelines
Integrating DAST into CI/CD pipelines requires addressing unique challenges compared to SAST integration. DAST needs running applications, making it unsuitable for early pipeline stages. Testing duration varies significantly based on application size and complexity. Full DAST scans can take hours or even days, requiring strategic decisions about when and how to run tests.
# Jenkins pipeline with DAST integration
pipeline {
agent any
environment {
DAST_TARGET_URL = 'https://staging.example.com'
ZAP_PORT = '8090'
REPORT_DIR = 'security-reports'
}
stages {
stage('Deploy to Test Environment') {
steps {
script {
// Deploy application to isolated test environment
sh '''
docker-compose -f docker-compose.test.yml up -d
./scripts/wait-for-healthy.sh ${DAST_TARGET_URL}
'''
}
}
}
stage('DAST Baseline Scan') {
steps {
script {
// Quick baseline scan for rapid feedback
sh '''
docker run --rm -v $(pwd):/zap/wrk/:rw \
-t owasp/zap2docker-stable zap-baseline.py \
-t ${DAST_TARGET_URL} \
-J baseline-report.json \
-r baseline-report.html \
-c zap-baseline.conf
'''
// Parse results and fail on high-severity issues
def results = readJSON file: 'baseline-report.json'
def highRiskAlerts = results.site[0].alerts.findAll {
it.riskcode == '3'
}
if (highRiskAlerts.size() > 0) {
error "High-risk vulnerabilities found: ${highRiskAlerts}"
}
}
}
}
stage('DAST Full Scan') {
when {
anyOf {
branch 'main'
branch 'release/*'
expression { params.FULL_SECURITY_SCAN == true }
}
}
steps {
script {
// Comprehensive scan with authentication
sh '''
# Start ZAP in daemon mode
docker run --name zap-daemon -u zap \
-p ${ZAP_PORT}:8090 -d \
owasp/zap2docker-stable zap.sh -daemon \
-port 8090 -host 0.0.0.0 \
-config api.key=${ZAP_API_KEY}
# Wait for ZAP to start
sleep 20
# Configure authentication
python3 scripts/zap_auth_setup.py \
--zap-url http://localhost:${ZAP_PORT} \
--target-url ${DAST_TARGET_URL} \
--auth-script auth/login_script.js
# Run full scan
python3 scripts/zap_full_scan.py \
--zap-url http://localhost:${ZAP_PORT} \
--target-url ${DAST_TARGET_URL} \
--scan-policy "Default Policy" \
--max-duration 3600
# Generate reports
curl "http://localhost:${ZAP_PORT}/OTHER/core/other/htmlreport/?apikey=${ZAP_API_KEY}" \
-o ${REPORT_DIR}/full-scan-report.html
'''
}
}
post {
always {
sh 'docker stop zap-daemon && docker rm zap-daemon'
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: "${REPORT_DIR}",
reportFiles: '*.html',
reportName: 'DAST Security Report'
])
}
}
}
}
}
Ephemeral test environments enable parallel DAST execution without conflicts. Container orchestration platforms like Kubernetes facilitate spinning up isolated application instances for security testing. Each pipeline run gets its own environment, preventing test interference and enabling multiple concurrent scans. These environments should mirror production configurations while remaining isolated from sensitive data.