Initial commit
This commit is contained in:
9
skills/appsec/dast-zap/assets/.gitkeep
Normal file
9
skills/appsec/dast-zap/assets/.gitkeep
Normal file
@@ -0,0 +1,9 @@
|
||||
# Assets Directory
|
||||
|
||||
Place files that will be used in the output Claude produces:
|
||||
- Templates
|
||||
- Configuration files
|
||||
- Images/logos
|
||||
- Boilerplate code
|
||||
|
||||
These files are NOT loaded into context but copied/modified in output.
|
||||
207
skills/appsec/dast-zap/assets/github_action.yml
Normal file
207
skills/appsec/dast-zap/assets/github_action.yml
Normal file
@@ -0,0 +1,207 @@
|
||||
# GitHub Actions Workflow for OWASP ZAP Security Scanning
|
||||
# Place this file in .github/workflows/zap-security-scan.yml
|
||||
|
||||
name: OWASP ZAP Security Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
schedule:
|
||||
# Run weekly security scans on Sunday at 2 AM
|
||||
- cron: '0 2 * * 0'
|
||||
workflow_dispatch: # Allow manual triggering
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write # For uploading SARIF reports
|
||||
issues: write # For creating security issues
|
||||
|
||||
jobs:
|
||||
zap-baseline-scan:
|
||||
name: ZAP Baseline Scan (PR/Push)
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request' || github.event_name == 'push'
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run ZAP Baseline Scan
|
||||
uses: zaproxy/action-baseline@v0.10.0
|
||||
with:
|
||||
target: ${{ secrets.STAGING_URL }}
|
||||
rules_file_name: '.zap/rules.tsv'
|
||||
cmd_options: '-a -j'
|
||||
fail_action: true
|
||||
allow_issue_writing: false
|
||||
|
||||
- name: Upload ZAP Scan Report
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: zap-baseline-report
|
||||
path: |
|
||||
report_html.html
|
||||
report_json.json
|
||||
retention-days: 30
|
||||
|
||||
- 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: '🔒 ZAP Baseline Scan Found Security Issues',
|
||||
body: 'ZAP baseline scan detected security vulnerabilities. Please review the scan report in the workflow artifacts.',
|
||||
labels: ['security', 'automated']
|
||||
})
|
||||
|
||||
zap-full-scan:
|
||||
name: ZAP Full Active Scan (Staging)
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/develop' || github.event_name == 'schedule'
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run ZAP Full Scan
|
||||
uses: zaproxy/action-full-scan@v0.8.0
|
||||
with:
|
||||
target: ${{ secrets.STAGING_URL }}
|
||||
rules_file_name: '.zap/rules.tsv'
|
||||
cmd_options: '-a -j -x report.xml'
|
||||
fail_action: true
|
||||
allow_issue_writing: true
|
||||
issue_title: 'ZAP Full Scan: Security Vulnerabilities Detected'
|
||||
|
||||
- name: Upload ZAP Full Scan Report
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: zap-full-scan-report
|
||||
path: |
|
||||
report_html.html
|
||||
report_json.json
|
||||
report.xml
|
||||
retention-days: 90
|
||||
|
||||
- name: Upload SARIF Report to GitHub Security
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: report.xml
|
||||
|
||||
zap-api-scan:
|
||||
name: ZAP API Scan
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' || github.event_name == 'pull_request'
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run ZAP API Scan
|
||||
uses: zaproxy/action-api-scan@v0.6.0
|
||||
with:
|
||||
target: ${{ secrets.API_URL }}
|
||||
format: openapi
|
||||
api_spec_file: './openapi.yaml'
|
||||
cmd_options: '-a -j'
|
||||
fail_action: true
|
||||
|
||||
- name: Upload API Scan Report
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: zap-api-scan-report
|
||||
path: |
|
||||
report_html.html
|
||||
report_json.json
|
||||
retention-days: 30
|
||||
|
||||
zap-authenticated-scan:
|
||||
name: ZAP Authenticated Scan
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/develop'
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Run Authenticated Scan
|
||||
env:
|
||||
APP_PASSWORD: ${{ secrets.TEST_USER_PASSWORD }}
|
||||
TARGET_URL: ${{ secrets.STAGING_URL }}
|
||||
run: |
|
||||
python3 scripts/zap_auth_scanner.py \
|
||||
--target $TARGET_URL \
|
||||
--auth-type form \
|
||||
--login-url $TARGET_URL/login \
|
||||
--username testuser \
|
||||
--password-env APP_PASSWORD \
|
||||
--output ./authenticated-scan-report.html
|
||||
|
||||
- name: Upload Authenticated Scan Report
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: zap-authenticated-scan-report
|
||||
path: authenticated-scan-report.*
|
||||
retention-days: 90
|
||||
|
||||
security-gate:
|
||||
name: Security Gate Check
|
||||
runs-on: ubuntu-latest
|
||||
needs: [zap-baseline-scan]
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Download Scan Results
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: zap-baseline-report
|
||||
|
||||
- name: Check Security Thresholds
|
||||
run: |
|
||||
# Install jq for JSON parsing
|
||||
sudo apt-get update && sudo apt-get install -y jq
|
||||
|
||||
# Count high and medium findings
|
||||
HIGH_COUNT=$(jq '[.site[].alerts[] | select(.risk == "High")] | length' report_json.json)
|
||||
MEDIUM_COUNT=$(jq '[.site[].alerts[] | select(.risk == "Medium")] | length' report_json.json)
|
||||
|
||||
echo "High risk findings: $HIGH_COUNT"
|
||||
echo "Medium risk findings: $MEDIUM_COUNT"
|
||||
|
||||
# Fail if thresholds exceeded
|
||||
if [ "$HIGH_COUNT" -gt 0 ]; then
|
||||
echo "❌ Security gate failed: $HIGH_COUNT high-risk vulnerabilities found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$MEDIUM_COUNT" -gt 10 ]; then
|
||||
echo "❌ Security gate failed: $MEDIUM_COUNT medium-risk vulnerabilities (max: 10)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Security gate passed"
|
||||
|
||||
- name: Post Summary
|
||||
if: always()
|
||||
run: |
|
||||
echo "## Security Scan Summary" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Risk Level | Count |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|------------|-------|" >> $GITHUB_STEP_SUMMARY
|
||||
jq -r '.site[].alerts[] | .risk' report_json.json | sort | uniq -c | \
|
||||
awk '{print "| " $2 " | " $1 " |"}' >> $GITHUB_STEP_SUMMARY
|
||||
226
skills/appsec/dast-zap/assets/gitlab_ci.yml
Normal file
226
skills/appsec/dast-zap/assets/gitlab_ci.yml
Normal file
@@ -0,0 +1,226 @@
|
||||
# GitLab CI/CD Pipeline for OWASP ZAP Security Scanning
|
||||
# Add this to your .gitlab-ci.yml file
|
||||
|
||||
stages:
|
||||
- security
|
||||
- report
|
||||
|
||||
variables:
|
||||
ZAP_IMAGE: "zaproxy/zap-stable:latest"
|
||||
STAGING_URL: "https://staging.example.com"
|
||||
REPORTS_DIR: "security-reports"
|
||||
|
||||
# Baseline scan for all merge requests
|
||||
zap_baseline_scan:
|
||||
stage: security
|
||||
image: docker:latest
|
||||
services:
|
||||
- docker:dind
|
||||
script:
|
||||
- mkdir -p $REPORTS_DIR
|
||||
- |
|
||||
docker run --rm \
|
||||
-v $(pwd)/$REPORTS_DIR:/zap/wrk/:rw \
|
||||
$ZAP_IMAGE \
|
||||
zap-baseline.py \
|
||||
-t $STAGING_URL \
|
||||
-r /zap/wrk/baseline-report.html \
|
||||
-J /zap/wrk/baseline-report.json \
|
||||
-w /zap/wrk/baseline-report.md \
|
||||
|| true
|
||||
- echo "Baseline scan completed"
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $REPORTS_DIR/
|
||||
reports:
|
||||
junit: $REPORTS_DIR/baseline-report.xml
|
||||
expire_in: 1 week
|
||||
only:
|
||||
- merge_requests
|
||||
- develop
|
||||
- main
|
||||
tags:
|
||||
- docker
|
||||
|
||||
# Full active scan (manual trigger for staging)
|
||||
zap_full_scan:
|
||||
stage: security
|
||||
image: docker:latest
|
||||
services:
|
||||
- docker:dind
|
||||
script:
|
||||
- mkdir -p $REPORTS_DIR
|
||||
- |
|
||||
docker run --rm \
|
||||
-v $(pwd)/$REPORTS_DIR:/zap/wrk/:rw \
|
||||
-v $(pwd)/.zap:/zap/config/:ro \
|
||||
$ZAP_IMAGE \
|
||||
zap-full-scan.py \
|
||||
-t $STAGING_URL \
|
||||
-c /zap/config/rules.tsv \
|
||||
-r /zap/wrk/full-scan-report.html \
|
||||
-J /zap/wrk/full-scan-report.json \
|
||||
-x /zap/wrk/full-scan-report.xml \
|
||||
|| true
|
||||
# Check for high-risk findings
|
||||
- |
|
||||
if command -v jq &> /dev/null; then
|
||||
HIGH_COUNT=$(jq '[.site[].alerts[] | select(.risk == "High")] | length' $REPORTS_DIR/full-scan-report.json)
|
||||
echo "High risk findings: $HIGH_COUNT"
|
||||
if [ "$HIGH_COUNT" -gt 0 ]; then
|
||||
echo "❌ Security scan failed: $HIGH_COUNT high-risk vulnerabilities"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $REPORTS_DIR/
|
||||
expire_in: 4 weeks
|
||||
only:
|
||||
- develop
|
||||
when: manual
|
||||
allow_failure: false
|
||||
tags:
|
||||
- docker
|
||||
|
||||
# API security scan
|
||||
zap_api_scan:
|
||||
stage: security
|
||||
image: docker:latest
|
||||
services:
|
||||
- docker:dind
|
||||
script:
|
||||
- mkdir -p $REPORTS_DIR
|
||||
- |
|
||||
if [ -f "openapi.yaml" ]; then
|
||||
docker run --rm \
|
||||
-v $(pwd)/$REPORTS_DIR:/zap/wrk/:rw \
|
||||
-v $(pwd):/zap/specs/:ro \
|
||||
$ZAP_IMAGE \
|
||||
zap-api-scan.py \
|
||||
-t $STAGING_URL \
|
||||
-f openapi \
|
||||
-d /zap/specs/openapi.yaml \
|
||||
-r /zap/wrk/api-scan-report.html \
|
||||
-J /zap/wrk/api-scan-report.json \
|
||||
|| true
|
||||
else
|
||||
echo "OpenAPI specification not found, skipping API scan"
|
||||
fi
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $REPORTS_DIR/
|
||||
expire_in: 1 week
|
||||
only:
|
||||
- merge_requests
|
||||
- develop
|
||||
allow_failure: true
|
||||
tags:
|
||||
- docker
|
||||
|
||||
# Authenticated scan (requires test credentials)
|
||||
zap_authenticated_scan:
|
||||
stage: security
|
||||
image: python:3.11-slim
|
||||
before_script:
|
||||
- apt-get update && apt-get install -y docker.io
|
||||
script:
|
||||
- mkdir -p $REPORTS_DIR
|
||||
- |
|
||||
python3 scripts/zap_auth_scanner.py \
|
||||
--target $STAGING_URL \
|
||||
--auth-type form \
|
||||
--login-url $STAGING_URL/login \
|
||||
--username $TEST_USERNAME \
|
||||
--password-env TEST_PASSWORD \
|
||||
--output $REPORTS_DIR/authenticated-scan-report.html
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $REPORTS_DIR/
|
||||
expire_in: 4 weeks
|
||||
only:
|
||||
- develop
|
||||
when: manual
|
||||
tags:
|
||||
- docker
|
||||
|
||||
# Security gate - check thresholds
|
||||
security_gate:
|
||||
stage: report
|
||||
image: alpine:latest
|
||||
before_script:
|
||||
- apk add --no-cache jq
|
||||
script:
|
||||
- |
|
||||
if [ -f "$REPORTS_DIR/baseline-report.json" ]; then
|
||||
HIGH_COUNT=$(jq '[.site[].alerts[] | select(.risk == "High")] | length' $REPORTS_DIR/baseline-report.json)
|
||||
MEDIUM_COUNT=$(jq '[.site[].alerts[] | select(.risk == "Medium")] | length' $REPORTS_DIR/baseline-report.json)
|
||||
|
||||
echo "==================================="
|
||||
echo "Security Scan Results"
|
||||
echo "==================================="
|
||||
echo "High risk findings: $HIGH_COUNT"
|
||||
echo "Medium risk findings: $MEDIUM_COUNT"
|
||||
echo "==================================="
|
||||
|
||||
# Fail on high-risk findings
|
||||
if [ "$HIGH_COUNT" -gt 0 ]; then
|
||||
echo "❌ Build failed: High-risk vulnerabilities detected"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Warn on medium-risk findings above threshold
|
||||
if [ "$MEDIUM_COUNT" -gt 10 ]; then
|
||||
echo "⚠️ Warning: $MEDIUM_COUNT medium-risk findings (threshold: 10)"
|
||||
fi
|
||||
|
||||
echo "✅ Security gate passed"
|
||||
else
|
||||
echo "No scan report found, skipping security gate"
|
||||
fi
|
||||
dependencies:
|
||||
- zap_baseline_scan
|
||||
only:
|
||||
- merge_requests
|
||||
- develop
|
||||
- main
|
||||
|
||||
# Generate consolidated report
|
||||
generate_report:
|
||||
stage: report
|
||||
image: alpine:latest
|
||||
before_script:
|
||||
- apk add --no-cache jq curl
|
||||
script:
|
||||
- |
|
||||
echo "# Security Scan Report" > $REPORTS_DIR/summary.md
|
||||
echo "" >> $REPORTS_DIR/summary.md
|
||||
echo "**Scan Date:** $(date)" >> $REPORTS_DIR/summary.md
|
||||
echo "**Target:** $STAGING_URL" >> $REPORTS_DIR/summary.md
|
||||
echo "" >> $REPORTS_DIR/summary.md
|
||||
echo "## Findings Summary" >> $REPORTS_DIR/summary.md
|
||||
echo "" >> $REPORTS_DIR/summary.md
|
||||
|
||||
if [ -f "$REPORTS_DIR/baseline-report.json" ]; then
|
||||
echo "| Risk Level | Count |" >> $REPORTS_DIR/summary.md
|
||||
echo "|------------|-------|" >> $REPORTS_DIR/summary.md
|
||||
jq -r '.site[].alerts[] | .risk' $REPORTS_DIR/baseline-report.json | \
|
||||
sort | uniq -c | awk '{print "| " $2 " | " $1 " |"}' >> $REPORTS_DIR/summary.md
|
||||
fi
|
||||
|
||||
cat $REPORTS_DIR/summary.md
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $REPORTS_DIR/summary.md
|
||||
expire_in: 4 weeks
|
||||
dependencies:
|
||||
- zap_baseline_scan
|
||||
only:
|
||||
- merge_requests
|
||||
- develop
|
||||
- main
|
||||
196
skills/appsec/dast-zap/assets/zap_automation.yaml
Normal file
196
skills/appsec/dast-zap/assets/zap_automation.yaml
Normal file
@@ -0,0 +1,196 @@
|
||||
# OWASP ZAP Automation Framework Configuration
|
||||
# Complete automation workflow for web application security testing
|
||||
|
||||
env:
|
||||
contexts:
|
||||
- name: WebApp-Security-Scan
|
||||
urls:
|
||||
- ${TARGET_URL}
|
||||
includePaths:
|
||||
- ${TARGET_URL}.*
|
||||
excludePaths:
|
||||
- .*logout.*
|
||||
- .*signout.*
|
||||
- .*\\.css
|
||||
- .*\\.js
|
||||
- .*\\.png
|
||||
- .*\\.jpg
|
||||
- .*\\.gif
|
||||
- .*\\.svg
|
||||
authentication:
|
||||
method: form
|
||||
parameters:
|
||||
loginUrl: ${LOGIN_URL}
|
||||
loginRequestData: username={%username%}&password={%password%}
|
||||
verification:
|
||||
method: response
|
||||
loggedInRegex: "\\QWelcome\\E"
|
||||
loggedOutRegex: "\\QLogin\\E"
|
||||
sessionManagement:
|
||||
method: cookie
|
||||
parameters:
|
||||
sessionCookieName: JSESSIONID
|
||||
users:
|
||||
- name: test-user
|
||||
credentials:
|
||||
username: ${TEST_USERNAME}
|
||||
password: ${TEST_PASSWORD}
|
||||
|
||||
parameters:
|
||||
failOnError: true
|
||||
failOnWarning: false
|
||||
progressToStdout: true
|
||||
|
||||
vars:
|
||||
target_url: ${TARGET_URL}
|
||||
api_key: ${ZAP_API_KEY}
|
||||
|
||||
jobs:
|
||||
# Environment setup
|
||||
- type: environment
|
||||
parameters:
|
||||
deleteGlobalAlerts: true
|
||||
updateAddOns: true
|
||||
|
||||
# Import OpenAPI specification (if available)
|
||||
- type: openapi
|
||||
parameters:
|
||||
apiFile: ${OPENAPI_SPEC_FILE}
|
||||
apiUrl: ${TARGET_URL}
|
||||
targetUrl: ${TARGET_URL}
|
||||
context: WebApp-Security-Scan
|
||||
optional: true
|
||||
|
||||
# Spider crawling
|
||||
- type: spider
|
||||
parameters:
|
||||
context: WebApp-Security-Scan
|
||||
user: test-user
|
||||
maxDuration: 10
|
||||
maxDepth: 5
|
||||
maxChildren: 10
|
||||
acceptCookies: true
|
||||
handleODataParametersVisited: true
|
||||
parseComments: true
|
||||
parseRobotsTxt: true
|
||||
parseSitemapXml: true
|
||||
parseSVNEntries: true
|
||||
parseGit: true
|
||||
postForm: true
|
||||
processForm: true
|
||||
requestWaitTime: 200
|
||||
|
||||
# AJAX Spider for JavaScript-heavy applications
|
||||
- type: spiderAjax
|
||||
parameters:
|
||||
context: WebApp-Security-Scan
|
||||
user: test-user
|
||||
maxDuration: 10
|
||||
maxCrawlDepth: 5
|
||||
numberOfBrowsers: 2
|
||||
browserId: firefox-headless
|
||||
clickDefaultElems: true
|
||||
clickElemsOnce: true
|
||||
eventWait: 1000
|
||||
reloadWait: 1000
|
||||
optional: true
|
||||
|
||||
# Wait for passive scanning to complete
|
||||
- type: passiveScan-wait
|
||||
parameters:
|
||||
maxDuration: 5
|
||||
|
||||
# Configure passive scan rules
|
||||
- type: passiveScan-config
|
||||
parameters:
|
||||
maxAlertsPerRule: 10
|
||||
scanOnlyInScope: true
|
||||
enableTags: true
|
||||
disableRules:
|
||||
- 10096 # Timestamp Disclosure (informational)
|
||||
|
||||
# Active scanning
|
||||
- type: activeScan
|
||||
parameters:
|
||||
context: WebApp-Security-Scan
|
||||
user: test-user
|
||||
policy: Default Policy
|
||||
maxRuleDurationInMins: 5
|
||||
maxScanDurationInMins: 30
|
||||
addQueryParam: false
|
||||
defaultPolicy: Default Policy
|
||||
delayInMs: 0
|
||||
handleAntiCSRFTokens: true
|
||||
injectPluginIdInHeader: false
|
||||
scanHeadersAllRequests: false
|
||||
threadPerHost: 2
|
||||
|
||||
# Wait for active scanning to complete
|
||||
- type: activeScan-wait
|
||||
|
||||
# Generate reports
|
||||
- type: report
|
||||
parameters:
|
||||
template: traditional-html
|
||||
reportDir: ${REPORT_DIR}
|
||||
reportFile: security-report.html
|
||||
reportTitle: Web Application Security Assessment
|
||||
reportDescription: Automated DAST scan using OWASP ZAP
|
||||
displayReport: false
|
||||
|
||||
- type: report
|
||||
parameters:
|
||||
template: traditional-json
|
||||
reportDir: ${REPORT_DIR}
|
||||
reportFile: security-report.json
|
||||
reportTitle: Web Application Security Assessment
|
||||
|
||||
- type: report
|
||||
parameters:
|
||||
template: traditional-xml
|
||||
reportDir: ${REPORT_DIR}
|
||||
reportFile: security-report.xml
|
||||
reportTitle: Web Application Security Assessment
|
||||
|
||||
- type: report
|
||||
parameters:
|
||||
template: sarif-json
|
||||
reportDir: ${REPORT_DIR}
|
||||
reportFile: security-report.sarif
|
||||
reportTitle: Web Application Security Assessment (SARIF)
|
||||
optional: true
|
||||
|
||||
# Alert filters (false positive suppression)
|
||||
alertFilters:
|
||||
- ruleId: 10021
|
||||
newRisk: Info
|
||||
url: ".*\\.css|.*\\.js|.*cdn\\..*"
|
||||
context: WebApp-Security-Scan
|
||||
|
||||
- ruleId: 10096
|
||||
newRisk: Info
|
||||
url: ".*api\\..*"
|
||||
parameter: "created_at|updated_at|timestamp"
|
||||
context: WebApp-Security-Scan
|
||||
|
||||
# Scan policies
|
||||
policies:
|
||||
- name: Default Policy
|
||||
defaultStrength: Medium
|
||||
defaultThreshold: Medium
|
||||
rules:
|
||||
- id: 40018 # SQL Injection
|
||||
strength: High
|
||||
threshold: Low
|
||||
- id: 40012 # Cross-Site Scripting (Reflected)
|
||||
strength: High
|
||||
threshold: Low
|
||||
- id: 40014 # Cross-Site Scripting (Persistent)
|
||||
strength: High
|
||||
threshold: Low
|
||||
- id: 90019 # Server-Side Code Injection
|
||||
strength: High
|
||||
threshold: Low
|
||||
- id: 90020 # Remote OS Command Injection
|
||||
strength: High
|
||||
threshold: Low
|
||||
192
skills/appsec/dast-zap/assets/zap_context.xml
Normal file
192
skills/appsec/dast-zap/assets/zap_context.xml
Normal file
@@ -0,0 +1,192 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
OWASP ZAP Authentication Context Template
|
||||
Configure this file for form-based, HTTP, or script-based authentication
|
||||
-->
|
||||
<configuration>
|
||||
<context>
|
||||
<!-- Context Name -->
|
||||
<name>WebApp-Auth-Context</name>
|
||||
<desc>Authentication context for web application security testing</desc>
|
||||
|
||||
<!-- Enable context -->
|
||||
<inscope>true</inscope>
|
||||
|
||||
<!-- URL Scope Definition -->
|
||||
<!-- Include all URLs under target domain -->
|
||||
<incregexes>https://app\.example\.com/.*</incregexes>
|
||||
|
||||
<!-- Exclude logout and static content -->
|
||||
<excregexes>https://app\.example\.com/logout</excregexes>
|
||||
<excregexes>https://app\.example\.com/signout</excregexes>
|
||||
<excregexes>https://app\.example\.com/static/.*</excregexes>
|
||||
<excregexes>.*\.css</excregexes>
|
||||
<excregexes>.*\.js</excregexes>
|
||||
<excregexes>.*\.png|.*\.jpg|.*\.gif</excregexes>
|
||||
|
||||
<!-- Technology Detection -->
|
||||
<tech>
|
||||
<include>Language</include>
|
||||
<include>Language.JavaScript</include>
|
||||
<include>OS</include>
|
||||
<include>OS.Linux</include>
|
||||
<include>WS</include>
|
||||
</tech>
|
||||
|
||||
<!-- Authentication Configuration -->
|
||||
<authentication>
|
||||
<!--
|
||||
Authentication Types:
|
||||
- formBasedAuthentication: Traditional login forms
|
||||
- httpAuthentication: HTTP Basic/Digest/NTLM
|
||||
- scriptBasedAuthentication: Custom authentication via script
|
||||
-->
|
||||
<type>formBasedAuthentication</type>
|
||||
|
||||
<!-- Form-Based Authentication -->
|
||||
<form>
|
||||
<!-- Login URL -->
|
||||
<loginurl>https://app.example.com/login</loginurl>
|
||||
|
||||
<!-- Login Request Body (POST parameters) -->
|
||||
<!-- Use {%username%} and {%password%} as placeholders -->
|
||||
<loginbody>username={%username%}&password={%password%}&csrf_token={%csrf_token%}</loginbody>
|
||||
|
||||
<!-- Login Page URL (where login form is displayed) -->
|
||||
<loginpageurl>https://app.example.com/login</loginpageurl>
|
||||
</form>
|
||||
|
||||
<!-- HTTP Authentication (uncomment if using) -->
|
||||
<!--
|
||||
<http>
|
||||
<realm>Protected Area</realm>
|
||||
<hostname>app.example.com</hostname>
|
||||
<port>443</port>
|
||||
</http>
|
||||
-->
|
||||
|
||||
<!-- Logged-In Indicator (regex pattern that appears when logged in) -->
|
||||
<!-- This helps ZAP determine if authentication succeeded -->
|
||||
<loggedin>\QWelcome,\E</loggedin>
|
||||
<!-- Alternative patterns:
|
||||
<loggedin>\QLogout\E</loggedin>
|
||||
<loggedin>\Qdashboard\E</loggedin>
|
||||
<loggedin>class="user-menu"</loggedin>
|
||||
-->
|
||||
|
||||
<!-- Logged-Out Indicator (regex pattern that appears when logged out) -->
|
||||
<loggedout>\QYou are not logged in\E</loggedout>
|
||||
<!-- Alternative patterns:
|
||||
<loggedout>\QLogin\E</loggedout>
|
||||
<loggedout>\QSign In\E</loggedout>
|
||||
-->
|
||||
|
||||
<!-- Poll URL for verification (optional) -->
|
||||
<pollurl>https://app.example.com/api/session/verify</pollurl>
|
||||
<polldata></polldata>
|
||||
<pollfreq>60</pollfreq>
|
||||
</authentication>
|
||||
|
||||
<!-- Session Management -->
|
||||
<sessionManagement>
|
||||
<!--
|
||||
Session Management Types:
|
||||
- cookieBasedSessionManagement: Session via cookies (most common)
|
||||
- httpAuthSessionManagement: HTTP authentication
|
||||
- scriptBasedSessionManagement: Custom session handling
|
||||
-->
|
||||
<type>cookieBasedSessionManagement</type>
|
||||
|
||||
<!-- Session cookies to monitor -->
|
||||
<sessioncookies>
|
||||
<cookie>JSESSIONID</cookie>
|
||||
<cookie>PHPSESSID</cookie>
|
||||
<cookie>sessionid</cookie>
|
||||
<cookie>session_token</cookie>
|
||||
</sessioncookies>
|
||||
</sessionManagement>
|
||||
|
||||
<!-- Test Users -->
|
||||
<users>
|
||||
<!-- User 1: Standard test user -->
|
||||
<user>
|
||||
<name>testuser</name>
|
||||
<enabled>true</enabled>
|
||||
<credentials>
|
||||
<credential>
|
||||
<name>username</name>
|
||||
<value>testuser</value>
|
||||
</credential>
|
||||
<credential>
|
||||
<name>password</name>
|
||||
<value>TestPassword123!</value>
|
||||
</credential>
|
||||
<!-- CSRF token (if needed) -->
|
||||
<!--
|
||||
<credential>
|
||||
<name>csrf_token</name>
|
||||
<value></value>
|
||||
</credential>
|
||||
-->
|
||||
</credentials>
|
||||
</user>
|
||||
|
||||
<!-- User 2: Admin user (if testing authorization) -->
|
||||
<user>
|
||||
<name>adminuser</name>
|
||||
<enabled>false</enabled>
|
||||
<credentials>
|
||||
<credential>
|
||||
<name>username</name>
|
||||
<value>adminuser</value>
|
||||
</credential>
|
||||
<credential>
|
||||
<name>password</name>
|
||||
<value>AdminPassword123!</value>
|
||||
</credential>
|
||||
</credentials>
|
||||
</user>
|
||||
</users>
|
||||
|
||||
<!-- Forced User Mode (for authorization testing) -->
|
||||
<!--
|
||||
Enables testing if authenticated user can access resources
|
||||
they shouldn't have access to
|
||||
-->
|
||||
<forcedUserMode>false</forcedUserMode>
|
||||
|
||||
<!-- Data Driven Nodes -->
|
||||
<!--
|
||||
For testing parameters with different values
|
||||
-->
|
||||
<datadrivennodes>
|
||||
<node>
|
||||
<name>user_id</name>
|
||||
<url>https://app.example.com/api/users/{user_id}</url>
|
||||
</node>
|
||||
</datadrivennodes>
|
||||
</context>
|
||||
|
||||
<!-- Global Exclude URLs (applied to all contexts) -->
|
||||
<globalexcludeurl>
|
||||
<regex>https://.*\.googleapis\.com/.*</regex>
|
||||
<regex>https://.*\.google-analytics\.com/.*</regex>
|
||||
<regex>https://.*\.googletagmanager\.com/.*</regex>
|
||||
<regex>https://cdn\..*</regex>
|
||||
</globalexcludeurl>
|
||||
|
||||
<!-- Anti-CSRF Token Configuration -->
|
||||
<anticsrf>
|
||||
<!-- Enable anti-CSRF token handling -->
|
||||
<enabled>true</enabled>
|
||||
|
||||
<!-- Token names to automatically detect and handle -->
|
||||
<tokennames>
|
||||
<tokenname>csrf_token</tokenname>
|
||||
<tokenname>csrftoken</tokenname>
|
||||
<tokenname>_csrf</tokenname>
|
||||
<tokenname>authenticity_token</tokenname>
|
||||
<tokenname>__RequestVerificationToken</tokenname>
|
||||
</tokennames>
|
||||
</anticsrf>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user