Initial commit
This commit is contained in:
40
skills/appsec/dast-zap/references/EXAMPLE.md
Normal file
40
skills/appsec/dast-zap/references/EXAMPLE.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Reference Document Template
|
||||
|
||||
This file contains detailed reference material that Claude should load only when needed.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Section 1](#section-1)
|
||||
- [Section 2](#section-2)
|
||||
- [Security Standards](#security-standards)
|
||||
|
||||
## Section 1
|
||||
|
||||
Detailed information, schemas, or examples that are too large for SKILL.md.
|
||||
|
||||
## Section 2
|
||||
|
||||
Additional reference material.
|
||||
|
||||
## Security Standards
|
||||
|
||||
### OWASP Top 10
|
||||
|
||||
Reference relevant OWASP categories:
|
||||
- A01: Broken Access Control
|
||||
- A02: Cryptographic Failures
|
||||
- etc.
|
||||
|
||||
### CWE Mappings
|
||||
|
||||
Map to relevant Common Weakness Enumeration categories:
|
||||
- CWE-79: Cross-site Scripting
|
||||
- CWE-89: SQL Injection
|
||||
- etc.
|
||||
|
||||
### MITRE ATT&CK
|
||||
|
||||
Reference relevant tactics and techniques if applicable:
|
||||
- TA0001: Initial Access
|
||||
- T1190: Exploit Public-Facing Application
|
||||
- etc.
|
||||
475
skills/appsec/dast-zap/references/api_testing_guide.md
Normal file
475
skills/appsec/dast-zap/references/api_testing_guide.md
Normal file
@@ -0,0 +1,475 @@
|
||||
# ZAP API Security Testing Guide
|
||||
|
||||
Advanced guide for testing REST, GraphQL, SOAP, and WebSocket APIs using OWASP ZAP.
|
||||
|
||||
## Overview
|
||||
|
||||
Modern applications rely heavily on APIs. This guide covers comprehensive API security testing patterns using ZAP's API scanning capabilities.
|
||||
|
||||
## API Types Supported
|
||||
|
||||
- **REST APIs** (JSON, XML)
|
||||
- **GraphQL APIs**
|
||||
- **SOAP APIs** (WSDL-based)
|
||||
- **gRPC APIs**
|
||||
- **WebSocket APIs**
|
||||
|
||||
## REST API Testing
|
||||
|
||||
### Testing with OpenAPI/Swagger Specification
|
||||
|
||||
**Best Practice:** Always use API specifications when available for complete coverage.
|
||||
|
||||
```bash
|
||||
# Basic OpenAPI scan
|
||||
docker run -v $(pwd):/zap/wrk/:rw -t zaproxy/zap-stable zap-api-scan.py \
|
||||
-t https://api.example.com \
|
||||
-f openapi \
|
||||
-d /zap/wrk/openapi.yaml \
|
||||
-r /zap/wrk/api-report.html
|
||||
```
|
||||
|
||||
### Testing Without Specification (Spider-Based)
|
||||
|
||||
When no specification is available:
|
||||
|
||||
```bash
|
||||
# Use standard spider with API context
|
||||
docker run -v $(pwd):/zap/wrk/:rw -t zaproxy/zap-stable zap-full-scan.py \
|
||||
-t https://api.example.com \
|
||||
-r /zap/wrk/api-report.html \
|
||||
-z "-config spider.parseComments=true -config spider.parseRobotsTxt=true"
|
||||
```
|
||||
|
||||
### Authentication Patterns
|
||||
|
||||
#### Bearer Token (JWT)
|
||||
|
||||
```bash
|
||||
# Obtain token first
|
||||
TOKEN=$(curl -X POST https://api.example.com/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"testuser","password":"password"}' \
|
||||
| jq -r '.access_token')
|
||||
|
||||
# Scan with authentication
|
||||
python3 scripts/zap_api_scan.py \
|
||||
--target https://api.example.com \
|
||||
--format openapi \
|
||||
--spec openapi.yaml \
|
||||
--header "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
#### API Key Authentication
|
||||
|
||||
```bash
|
||||
# API key in header
|
||||
python3 scripts/zap_api_scan.py \
|
||||
--target https://api.example.com \
|
||||
--format openapi \
|
||||
--spec openapi.yaml \
|
||||
--header "X-API-Key: your-api-key-here"
|
||||
|
||||
# API key in query parameter
|
||||
python3 scripts/zap_api_scan.py \
|
||||
--target https://api.example.com?api_key=your-api-key \
|
||||
--format openapi \
|
||||
--spec openapi.yaml
|
||||
```
|
||||
|
||||
### Common REST API Vulnerabilities
|
||||
|
||||
#### 1. Broken Object Level Authorization (BOLA)
|
||||
|
||||
**Detection:** Test access to resources belonging to other users.
|
||||
|
||||
**Manual Test:**
|
||||
```bash
|
||||
# Request resource with different user IDs
|
||||
curl -H "Authorization: Bearer $USER1_TOKEN" \
|
||||
https://api.example.com/users/123/profile
|
||||
|
||||
curl -H "Authorization: Bearer $USER2_TOKEN" \
|
||||
https://api.example.com/users/123/profile # Should be denied
|
||||
```
|
||||
|
||||
**ZAP Configuration:**
|
||||
Add authorization test scripts to detect BOLA.
|
||||
|
||||
#### 2. Mass Assignment
|
||||
|
||||
**Detection:** Send additional fields not in API specification.
|
||||
|
||||
**Test Payload:**
|
||||
```json
|
||||
{
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"is_admin": true, # Unauthorized field
|
||||
"role": "admin" # Unauthorized field
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Rate Limiting
|
||||
|
||||
**Detection:** Send multiple requests rapidly.
|
||||
|
||||
```bash
|
||||
# Test rate limiting
|
||||
for i in {1..100}; do
|
||||
curl https://api.example.com/endpoint -H "Authorization: Bearer $TOKEN"
|
||||
done
|
||||
```
|
||||
|
||||
**Expected:** HTTP 429 (Too Many Requests) after threshold.
|
||||
|
||||
## GraphQL API Testing
|
||||
|
||||
### Testing with GraphQL Schema
|
||||
|
||||
```bash
|
||||
# Scan GraphQL endpoint with schema
|
||||
docker run -v $(pwd):/zap/wrk/:rw -t zaproxy/zap-stable zap-api-scan.py \
|
||||
-t https://api.example.com/graphql \
|
||||
-f graphql \
|
||||
-d /zap/wrk/schema.graphql \
|
||||
-r /zap/wrk/graphql-report.html
|
||||
```
|
||||
|
||||
### GraphQL Introspection
|
||||
|
||||
**Check if introspection is enabled:**
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.example.com/graphql \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"query": "{ __schema { types { name } } }"}'
|
||||
```
|
||||
|
||||
**Security Note:** Disable introspection in production.
|
||||
|
||||
### GraphQL-Specific Vulnerabilities
|
||||
|
||||
#### 1. Query Depth/Complexity Attacks
|
||||
|
||||
**Malicious Query:**
|
||||
```graphql
|
||||
query {
|
||||
user {
|
||||
posts {
|
||||
comments {
|
||||
author {
|
||||
posts {
|
||||
comments {
|
||||
author {
|
||||
# ... deeply nested
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Mitigation:** Implement query depth/complexity limits.
|
||||
|
||||
#### 2. Batch Query Attacks
|
||||
|
||||
**Malicious Query:**
|
||||
```graphql
|
||||
query {
|
||||
user1: user(id: 1) { name email }
|
||||
user2: user(id: 2) { name email }
|
||||
# ... repeated hundreds of times
|
||||
user500: user(id: 500) { name email }
|
||||
}
|
||||
```
|
||||
|
||||
**Mitigation:** Limit batch query size.
|
||||
|
||||
#### 3. Field Suggestions
|
||||
|
||||
When introspection is disabled, test field suggestions:
|
||||
|
||||
```graphql
|
||||
query {
|
||||
user {
|
||||
nam # Intentional typo to trigger suggestions
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## SOAP API Testing
|
||||
|
||||
### Testing with WSDL
|
||||
|
||||
```bash
|
||||
# SOAP API scan with WSDL
|
||||
docker run -v $(pwd):/zap/wrk/:rw -t zaproxy/zap-stable zap-api-scan.py \
|
||||
-t https://api.example.com/soap \
|
||||
-f soap \
|
||||
-d /zap/wrk/service.wsdl \
|
||||
-r /zap/wrk/soap-report.html
|
||||
```
|
||||
|
||||
### SOAP-Specific Vulnerabilities
|
||||
|
||||
#### 1. XML External Entity (XXE)
|
||||
|
||||
**Test Payload:**
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
|
||||
<soap:Envelope>
|
||||
<soap:Body>
|
||||
<login>
|
||||
<username>&xxe;</username>
|
||||
</login>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
```
|
||||
|
||||
#### 2. XML Injection
|
||||
|
||||
**Test Payload:**
|
||||
```xml
|
||||
<username>admin</username><role>admin</role></user><user><username>attacker</username>
|
||||
```
|
||||
|
||||
## WebSocket Testing
|
||||
|
||||
### Manual WebSocket Testing
|
||||
|
||||
ZAP can intercept WebSocket traffic:
|
||||
|
||||
1. Configure browser proxy to ZAP
|
||||
2. Connect to WebSocket endpoint
|
||||
3. Review messages in ZAP's WebSocket tab
|
||||
4. Manually craft malicious messages
|
||||
|
||||
### Common WebSocket Vulnerabilities
|
||||
|
||||
- **Message Injection:** Inject malicious payloads in WebSocket messages
|
||||
- **Authentication Bypass:** Test if authentication is required for WebSocket connections
|
||||
- **Message Tampering:** Modify messages in transit
|
||||
|
||||
## API Security Testing Checklist
|
||||
|
||||
### Authentication & Authorization
|
||||
|
||||
- [ ] Test unauthenticated access to protected endpoints
|
||||
- [ ] Test authorization bypass (access other users' data)
|
||||
- [ ] Test JWT token validation (expiration, signature)
|
||||
- [ ] Test API key validation
|
||||
- [ ] Test role-based access control (RBAC)
|
||||
|
||||
### Input Validation
|
||||
|
||||
- [ ] Test SQL injection in parameters
|
||||
- [ ] Test NoSQL injection (MongoDB, etc.)
|
||||
- [ ] Test command injection
|
||||
- [ ] Test XML injection (for SOAP APIs)
|
||||
- [ ] Test mass assignment vulnerabilities
|
||||
- [ ] Test parameter pollution
|
||||
|
||||
### Rate Limiting & DoS
|
||||
|
||||
- [ ] Verify rate limiting is enforced
|
||||
- [ ] Test resource exhaustion (large payloads)
|
||||
- [ ] Test query complexity limits (GraphQL)
|
||||
- [ ] Test batch request limits
|
||||
|
||||
### Data Exposure
|
||||
|
||||
- [ ] Check for sensitive data in responses
|
||||
- [ ] Test verbose error messages
|
||||
- [ ] Verify PII is properly protected
|
||||
- [ ] Check for data leakage in logs
|
||||
|
||||
### Transport Security
|
||||
|
||||
- [ ] Verify HTTPS is enforced
|
||||
- [ ] Test TLS configuration (strong ciphers only)
|
||||
- [ ] Check certificate validation
|
||||
- [ ] Verify HSTS header is set
|
||||
|
||||
### Business Logic
|
||||
|
||||
- [ ] Test state manipulation
|
||||
- [ ] Test payment flow manipulation
|
||||
- [ ] Test workflow bypass
|
||||
- [ ] Test negative values/amounts
|
||||
|
||||
## ZAP Automation for API Testing
|
||||
|
||||
### Automation Framework Configuration
|
||||
|
||||
`api_automation.yaml`:
|
||||
|
||||
```yaml
|
||||
env:
|
||||
contexts:
|
||||
- name: API-Context
|
||||
urls:
|
||||
- https://api.example.com
|
||||
includePaths:
|
||||
- https://api.example.com/.*
|
||||
authentication:
|
||||
method: header
|
||||
parameters:
|
||||
header: Authorization
|
||||
value: "Bearer ${API_TOKEN}"
|
||||
|
||||
jobs:
|
||||
- type: openapi
|
||||
parameters:
|
||||
apiFile: /zap/wrk/openapi.yaml
|
||||
apiUrl: https://api.example.com
|
||||
targetUrl: https://api.example.com
|
||||
context: API-Context
|
||||
|
||||
- type: passiveScan-wait
|
||||
|
||||
- type: activeScan
|
||||
parameters:
|
||||
context: API-Context
|
||||
policy: API-Scan-Policy
|
||||
user: api-user
|
||||
|
||||
- type: report
|
||||
parameters:
|
||||
template: traditional-html
|
||||
reportDir: /zap/wrk/
|
||||
reportFile: api-security-report.html
|
||||
reportTitle: API Security Assessment
|
||||
```
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
export API_TOKEN="your-token-here"
|
||||
docker run -v $(pwd):/zap/wrk/:rw -t zaproxy/zap-stable \
|
||||
zap.sh -cmd -autorun /zap/wrk/api_automation.yaml
|
||||
```
|
||||
|
||||
## Custom API Scan Policies
|
||||
|
||||
### Create API-Optimized Scan Policy
|
||||
|
||||
Disable irrelevant checks for APIs:
|
||||
- Disable DOM XSS checks (no browser context)
|
||||
- Disable CSRF checks (stateless APIs)
|
||||
- Enable injection checks (SQL, NoSQL, Command)
|
||||
- Enable authentication/authorization checks
|
||||
|
||||
See `assets/scan_policy_api.policy` for pre-configured policy.
|
||||
|
||||
## API Testing Tools Integration
|
||||
|
||||
### Postman Integration
|
||||
|
||||
Export Postman collection to OpenAPI:
|
||||
|
||||
```bash
|
||||
# Use Postman's built-in export or newman
|
||||
newman run collection.json --export-collection openapi.yaml
|
||||
```
|
||||
|
||||
### cURL to OpenAPI Conversion
|
||||
|
||||
Use tools like `curl-to-openapi` to generate specs from cURL commands.
|
||||
|
||||
## Common API Testing Patterns
|
||||
|
||||
### Pattern 1: CRUD Operation Testing
|
||||
|
||||
Test all CRUD operations for each resource:
|
||||
|
||||
```bash
|
||||
# CREATE
|
||||
curl -X POST https://api.example.com/users \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-d '{"username":"testuser"}'
|
||||
|
||||
# READ
|
||||
curl https://api.example.com/users/123 \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
|
||||
# UPDATE
|
||||
curl -X PUT https://api.example.com/users/123 \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-d '{"username":"updated"}'
|
||||
|
||||
# DELETE
|
||||
curl -X DELETE https://api.example.com/users/123 \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
### Pattern 2: Multi-User Testing
|
||||
|
||||
Test with different user roles:
|
||||
|
||||
```bash
|
||||
# Admin user
|
||||
export ADMIN_TOKEN="admin-token"
|
||||
python3 scripts/zap_api_scan.py --target https://api.example.com \
|
||||
--header "Authorization: Bearer $ADMIN_TOKEN"
|
||||
|
||||
# Regular user
|
||||
export USER_TOKEN="user-token"
|
||||
python3 scripts/zap_api_scan.py --target https://api.example.com \
|
||||
--header "Authorization: Bearer $USER_TOKEN"
|
||||
```
|
||||
|
||||
### Pattern 3: Versioned API Testing
|
||||
|
||||
Test all API versions:
|
||||
|
||||
```bash
|
||||
# v1
|
||||
python3 scripts/zap_api_scan.py --target https://api.example.com/v1 \
|
||||
--spec openapi-v1.yaml
|
||||
|
||||
# v2
|
||||
python3 scripts/zap_api_scan.py --target https://api.example.com/v2 \
|
||||
--spec openapi-v2.yaml
|
||||
```
|
||||
|
||||
## Troubleshooting API Scans
|
||||
|
||||
### Issue: OpenAPI Import Fails
|
||||
|
||||
**Solution:** Validate OpenAPI spec:
|
||||
|
||||
```bash
|
||||
# Use Swagger Editor or openapi-validator
|
||||
npx @apidevtools/swagger-cli validate openapi.yaml
|
||||
```
|
||||
|
||||
### Issue: Authentication Not Working
|
||||
|
||||
**Solution:** Test authentication manually first:
|
||||
|
||||
```bash
|
||||
curl -v https://api.example.com/protected-endpoint \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
### Issue: Rate Limiting During Scan
|
||||
|
||||
**Solution:** Reduce scan speed:
|
||||
|
||||
```bash
|
||||
docker run -t zaproxy/zap-stable zap-api-scan.py \
|
||||
-t https://api.example.com -f openapi -d /zap/wrk/spec.yaml \
|
||||
-z "-config scanner.delayInMs=1000"
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [OWASP API Security Top 10](https://owasp.org/www-project-api-security/)
|
||||
- [REST API Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html)
|
||||
- [GraphQL Security](https://graphql.org/learn/authorization/)
|
||||
- [ZAP OpenAPI Add-on](https://www.zaproxy.org/docs/desktop/addons/openapi-support/)
|
||||
431
skills/appsec/dast-zap/references/authentication_guide.md
Normal file
431
skills/appsec/dast-zap/references/authentication_guide.md
Normal file
@@ -0,0 +1,431 @@
|
||||
# ZAP Authentication Configuration Guide
|
||||
|
||||
Comprehensive guide for configuring authenticated scanning in OWASP ZAP for form-based, token-based, and OAuth authentication.
|
||||
|
||||
## Overview
|
||||
|
||||
Authenticated scanning is critical for testing protected application areas that require login. ZAP supports multiple authentication methods:
|
||||
|
||||
- **Form-Based Authentication** - Traditional username/password login forms
|
||||
- **HTTP Authentication** - Basic, Digest, NTLM authentication
|
||||
- **Script-Based Authentication** - Custom authentication flows (OAuth, SAML)
|
||||
- **Token-Based Authentication** - Bearer tokens, API keys, JWT
|
||||
|
||||
## Form-Based Authentication
|
||||
|
||||
### Configuration Steps
|
||||
|
||||
1. **Identify Login Parameters**
|
||||
- Login URL
|
||||
- Username field name
|
||||
- Password field name
|
||||
- Submit button/action
|
||||
|
||||
2. **Create Authentication Context**
|
||||
|
||||
```bash
|
||||
# Use bundled script
|
||||
python3 scripts/zap_auth_scanner.py \
|
||||
--target https://app.example.com \
|
||||
--auth-type form \
|
||||
--login-url https://app.example.com/login \
|
||||
--username testuser \
|
||||
--password-env APP_PASSWORD \
|
||||
--verification-url https://app.example.com/dashboard \
|
||||
--output authenticated-scan-report.html
|
||||
```
|
||||
|
||||
3. **Configure Logged-In Indicator**
|
||||
|
||||
Specify a regex pattern that appears only when logged in:
|
||||
- Example: `Welcome, testuser`
|
||||
- Example: `<a href="/logout">Logout</a>`
|
||||
- Example: Check for presence of dashboard elements
|
||||
|
||||
### Manual Context Configuration
|
||||
|
||||
Create `auth-context.xml`:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<context>
|
||||
<name>WebAppAuth</name>
|
||||
<desc>Authenticated scanning context</desc>
|
||||
<inscope>true</inscope>
|
||||
<incregexes>https://app\.example\.com/.*</incregexes>
|
||||
|
||||
<authentication>
|
||||
<type>formBasedAuthentication</type>
|
||||
<form>
|
||||
<loginurl>https://app.example.com/login</loginurl>
|
||||
<loginbody>username={%username%}&password={%password%}</loginbody>
|
||||
<loginpageurl>https://app.example.com/login</loginpageurl>
|
||||
</form>
|
||||
<loggedin>\QWelcome,\E</loggedin>
|
||||
<loggedout>\QYou are not logged in\E</loggedout>
|
||||
</authentication>
|
||||
|
||||
<users>
|
||||
<user>
|
||||
<name>testuser</name>
|
||||
<credentials>
|
||||
<credential>
|
||||
<name>username</name>
|
||||
<value>testuser</value>
|
||||
</credential>
|
||||
<credential>
|
||||
<name>password</name>
|
||||
<value>SecureP@ssw0rd</value>
|
||||
</credential>
|
||||
</credentials>
|
||||
<enabled>true</enabled>
|
||||
</user>
|
||||
</users>
|
||||
|
||||
<sessionManagement>
|
||||
<type>cookieBasedSessionManagement</type>
|
||||
</sessionManagement>
|
||||
</context>
|
||||
</configuration>
|
||||
```
|
||||
|
||||
Run scan with context:
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
-v $(pwd):/zap/wrk/:rw \
|
||||
-t zaproxy/zap-stable \
|
||||
zap-full-scan.py \
|
||||
-t https://app.example.com \
|
||||
-n /zap/wrk/auth-context.xml \
|
||||
-r /zap/wrk/auth-report.html
|
||||
```
|
||||
|
||||
## Token-Based Authentication (Bearer Tokens)
|
||||
|
||||
### JWT/Bearer Token Configuration
|
||||
|
||||
1. **Obtain Authentication Token**
|
||||
|
||||
```bash
|
||||
# Example: Login to get token
|
||||
TOKEN=$(curl -X POST https://api.example.com/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"testuser","password":"password"}' \
|
||||
| jq -r '.token')
|
||||
```
|
||||
|
||||
2. **Configure ZAP to Include Token**
|
||||
|
||||
Use ZAP Replacer to add Authorization header:
|
||||
|
||||
```bash
|
||||
python3 scripts/zap_auth_scanner.py \
|
||||
--target https://api.example.com \
|
||||
--auth-type bearer \
|
||||
--token-env API_TOKEN \
|
||||
--output api-auth-scan.html
|
||||
```
|
||||
|
||||
### Manual Token Configuration
|
||||
|
||||
Using ZAP automation framework (`zap_automation.yaml`):
|
||||
|
||||
```yaml
|
||||
env:
|
||||
contexts:
|
||||
- name: API-Context
|
||||
urls:
|
||||
- https://api.example.com
|
||||
authentication:
|
||||
method: header
|
||||
parameters:
|
||||
header: Authorization
|
||||
value: "Bearer ${API_TOKEN}"
|
||||
sessionManagement:
|
||||
method: cookie
|
||||
|
||||
jobs:
|
||||
- type: spider
|
||||
parameters:
|
||||
context: API-Context
|
||||
user: api-user
|
||||
|
||||
- type: activeScan
|
||||
parameters:
|
||||
context: API-Context
|
||||
user: api-user
|
||||
```
|
||||
|
||||
## OAuth 2.0 Authentication
|
||||
|
||||
### Authorization Code Flow
|
||||
|
||||
1. **Manual Browser-Based Token Acquisition**
|
||||
|
||||
```bash
|
||||
# Step 1: Get authorization code (open in browser)
|
||||
https://oauth.example.com/authorize?
|
||||
client_id=YOUR_CLIENT_ID&
|
||||
redirect_uri=http://localhost:8080/callback&
|
||||
response_type=code&
|
||||
scope=openid profile
|
||||
|
||||
# Step 2: Exchange code for token
|
||||
TOKEN=$(curl -X POST https://oauth.example.com/token \
|
||||
-d "grant_type=authorization_code" \
|
||||
-d "code=AUTH_CODE_FROM_STEP_1" \
|
||||
-d "client_id=YOUR_CLIENT_ID" \
|
||||
-d "client_secret=YOUR_CLIENT_SECRET" \
|
||||
-d "redirect_uri=http://localhost:8080/callback" \
|
||||
| jq -r '.access_token')
|
||||
|
||||
# Step 3: Use token in ZAP scan
|
||||
export API_TOKEN="$TOKEN"
|
||||
python3 scripts/zap_auth_scanner.py \
|
||||
--target https://api.example.com \
|
||||
--auth-type bearer \
|
||||
--token-env API_TOKEN
|
||||
```
|
||||
|
||||
### Client Credentials Flow (Service-to-Service)
|
||||
|
||||
```bash
|
||||
# Obtain token using client credentials
|
||||
TOKEN=$(curl -X POST https://oauth.example.com/token \
|
||||
-d "grant_type=client_credentials" \
|
||||
-d "client_id=YOUR_CLIENT_ID" \
|
||||
-d "client_secret=YOUR_CLIENT_SECRET" \
|
||||
-d "scope=api.read api.write" \
|
||||
| jq -r '.access_token')
|
||||
|
||||
export API_TOKEN="$TOKEN"
|
||||
|
||||
# Run authenticated scan
|
||||
python3 scripts/zap_auth_scanner.py \
|
||||
--target https://api.example.com \
|
||||
--auth-type bearer \
|
||||
--token-env API_TOKEN
|
||||
```
|
||||
|
||||
## HTTP Basic/Digest Authentication
|
||||
|
||||
### Basic Authentication
|
||||
|
||||
```bash
|
||||
# Option 1: Using environment variable
|
||||
export BASIC_AUTH="dGVzdHVzZXI6cGFzc3dvcmQ=" # base64(testuser:password)
|
||||
|
||||
# Option 2: Using script
|
||||
python3 scripts/zap_auth_scanner.py \
|
||||
--target https://app.example.com \
|
||||
--auth-type http \
|
||||
--username testuser \
|
||||
--password-env HTTP_PASSWORD
|
||||
```
|
||||
|
||||
### Digest Authentication
|
||||
|
||||
Similar to Basic, but ZAP automatically handles the challenge-response:
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
-v $(pwd):/zap/wrk/:rw \
|
||||
-t zaproxy/zap-stable \
|
||||
zap-full-scan.py \
|
||||
-t https://app.example.com \
|
||||
-n /zap/wrk/digest-auth-context.xml \
|
||||
-r /zap/wrk/digest-auth-report.html
|
||||
```
|
||||
|
||||
## Session Management
|
||||
|
||||
### Cookie-Based Sessions
|
||||
|
||||
**Default Behavior:** ZAP automatically manages cookies.
|
||||
|
||||
**Custom Configuration:**
|
||||
- Set session cookie name in context
|
||||
- Configure session timeout
|
||||
- Define re-authentication triggers
|
||||
|
||||
### Token Refresh Handling
|
||||
|
||||
For tokens that expire during scan:
|
||||
|
||||
```yaml
|
||||
# zap_automation.yaml
|
||||
env:
|
||||
contexts:
|
||||
- name: API-Context
|
||||
authentication:
|
||||
method: script
|
||||
parameters:
|
||||
script: |
|
||||
// JavaScript to refresh token
|
||||
function authenticate(helper, paramsValues, credentials) {
|
||||
var loginUrl = "https://api.example.com/auth/login";
|
||||
var postData = '{"username":"' + credentials.getParam("username") +
|
||||
'","password":"' + credentials.getParam("password") + '"}';
|
||||
|
||||
var msg = helper.prepareMessage();
|
||||
msg.setRequestHeader("POST " + loginUrl + " HTTP/1.1");
|
||||
msg.setRequestBody(postData);
|
||||
helper.sendAndReceive(msg);
|
||||
|
||||
var response = msg.getResponseBody().toString();
|
||||
var token = JSON.parse(response).token;
|
||||
|
||||
// Store token for use in requests
|
||||
helper.getHttpSender().setRequestHeader("Authorization", "Bearer " + token);
|
||||
return msg;
|
||||
}
|
||||
```
|
||||
|
||||
## Verification and Troubleshooting
|
||||
|
||||
### Verify Authentication is Working
|
||||
|
||||
1. **Check Logged-In Indicator**
|
||||
|
||||
Run a spider scan and verify protected pages are accessed:
|
||||
|
||||
```bash
|
||||
# Look for dashboard, profile, or other authenticated pages in spider results
|
||||
```
|
||||
|
||||
2. **Monitor Authentication Requests**
|
||||
|
||||
Enable ZAP logging to see authentication attempts:
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
-v $(pwd):/zap/wrk/:rw \
|
||||
-e ZAP_LOG_LEVEL=DEBUG \
|
||||
-t zaproxy/zap-stable \
|
||||
zap-full-scan.py -t https://app.example.com -n /zap/wrk/context.xml
|
||||
```
|
||||
|
||||
3. **Test with Manual Request**
|
||||
|
||||
Send a manual authenticated request via ZAP GUI or API to verify credentials work.
|
||||
|
||||
### Common Authentication Issues
|
||||
|
||||
#### Issue: Session Expires During Scan
|
||||
|
||||
**Solution:** Configure re-authentication:
|
||||
|
||||
```python
|
||||
# In zap_auth_scanner.py, add re-authentication trigger
|
||||
--re-authenticate-on 401,403 \
|
||||
--verification-interval 300 # Check every 5 minutes
|
||||
```
|
||||
|
||||
#### Issue: CSRF Tokens Required
|
||||
|
||||
**Solution:** Use anti-CSRF token handling:
|
||||
|
||||
```yaml
|
||||
# zap_automation.yaml
|
||||
env:
|
||||
contexts:
|
||||
- name: WebApp
|
||||
authentication:
|
||||
verification:
|
||||
method: response
|
||||
loggedInRegex: "\\QWelcome\\E"
|
||||
sessionManagement:
|
||||
method: cookie
|
||||
parameters:
|
||||
antiCsrfTokens: true
|
||||
```
|
||||
|
||||
#### Issue: Rate Limiting Blocking Authentication
|
||||
|
||||
**Solution:** Slow down scan:
|
||||
|
||||
```bash
|
||||
docker run -t zaproxy/zap-stable zap-full-scan.py \
|
||||
-t https://app.example.com \
|
||||
-z "-config scanner.delayInMs=2000 -config scanner.threadPerHost=1"
|
||||
```
|
||||
|
||||
#### Issue: Multi-Step Login (MFA)
|
||||
|
||||
**Solution:** Use script-based authentication with Selenium or manual token acquisition.
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
1. **Never Hardcode Credentials**
|
||||
- Use environment variables
|
||||
- Use secrets management tools (Vault, AWS Secrets Manager)
|
||||
|
||||
2. **Use Dedicated Test Accounts**
|
||||
- Create accounts specifically for security testing
|
||||
- Limit permissions to test data only
|
||||
- Monitor for abuse
|
||||
|
||||
3. **Rotate Credentials Regularly**
|
||||
- Change test account passwords after each scan
|
||||
- Rotate API tokens frequently
|
||||
|
||||
4. **Log Authentication Attempts**
|
||||
- Monitor for failed authentication attempts
|
||||
- Alert on unusual patterns
|
||||
|
||||
5. **Secure Context Files**
|
||||
- Never commit context files with credentials to version control
|
||||
- Use `.gitignore` to exclude `*.context` files
|
||||
- Encrypt context files at rest
|
||||
|
||||
## Examples by Framework
|
||||
|
||||
### Django Application
|
||||
|
||||
```bash
|
||||
# Django CSRF token handling
|
||||
python3 scripts/zap_auth_scanner.py \
|
||||
--target https://django-app.example.com \
|
||||
--auth-type form \
|
||||
--login-url https://django-app.example.com/accounts/login/ \
|
||||
--username testuser \
|
||||
--password-env DJANGO_PASSWORD \
|
||||
--verification-url https://django-app.example.com/dashboard/
|
||||
```
|
||||
|
||||
### Spring Boot Application
|
||||
|
||||
```bash
|
||||
# Spring Security form login
|
||||
python3 scripts/zap_auth_scanner.py \
|
||||
--target https://spring-app.example.com \
|
||||
--auth-type form \
|
||||
--login-url https://spring-app.example.com/login \
|
||||
--username testuser \
|
||||
--password-env SPRING_PASSWORD
|
||||
```
|
||||
|
||||
### React SPA with JWT
|
||||
|
||||
```bash
|
||||
# Get JWT from API, then scan
|
||||
TOKEN=$(curl -X POST https://api.example.com/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"test@example.com","password":"password"}' \
|
||||
| jq -r '.token')
|
||||
|
||||
export API_TOKEN="$TOKEN"
|
||||
|
||||
python3 scripts/zap_auth_scanner.py \
|
||||
--target https://spa.example.com \
|
||||
--auth-type bearer \
|
||||
--token-env API_TOKEN
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [ZAP Authentication Documentation](https://www.zaproxy.org/docs/desktop/start/features/authentication/)
|
||||
- [ZAP Session Management](https://www.zaproxy.org/docs/desktop/start/features/sessionmanagement/)
|
||||
- [OAuth 2.0 RFC 6749](https://tools.ietf.org/html/rfc6749)
|
||||
427
skills/appsec/dast-zap/references/false_positive_handling.md
Normal file
427
skills/appsec/dast-zap/references/false_positive_handling.md
Normal file
@@ -0,0 +1,427 @@
|
||||
# ZAP False Positive Handling Guide
|
||||
|
||||
Guide for identifying, verifying, and suppressing false positives in OWASP ZAP scan results.
|
||||
|
||||
## Overview
|
||||
|
||||
DAST tools like ZAP generate false positives - alerts for issues that aren't actually exploitable vulnerabilities. This guide helps you:
|
||||
|
||||
1. Identify common false positives
|
||||
2. Verify findings manually
|
||||
3. Suppress false positives in future scans
|
||||
4. Tune scan policies
|
||||
|
||||
## Common False Positives
|
||||
|
||||
### 1. X-Content-Type-Options Missing
|
||||
|
||||
**Alert:** Missing X-Content-Type-Options header
|
||||
|
||||
**False Positive Scenario:**
|
||||
- Static content served by CDNs
|
||||
- Third-party resources
|
||||
- Legacy browsers not supported
|
||||
|
||||
**Verification:**
|
||||
```bash
|
||||
curl -I https://example.com/static/script.js
|
||||
# Check if browser performs MIME sniffing
|
||||
```
|
||||
|
||||
**When to Suppress:**
|
||||
- Static content only (CSS, JS, images)
|
||||
- Content served from trusted CDN
|
||||
- No user-controlled content in responses
|
||||
|
||||
**Suppression Rule:**
|
||||
```tsv
|
||||
10021 https://cdn.example.com/.* .* 693 IGNORE
|
||||
```
|
||||
|
||||
### 2. Cookie Without Secure Flag
|
||||
|
||||
**Alert:** Cookie without Secure flag set
|
||||
|
||||
**False Positive Scenario:**
|
||||
- Development/testing environments (HTTP)
|
||||
- Non-sensitive cookies (analytics, preferences)
|
||||
- Localhost testing
|
||||
|
||||
**Verification:**
|
||||
```bash
|
||||
curl -I https://example.com
|
||||
# Check Set-Cookie headers
|
||||
# Verify if cookie contains sensitive data
|
||||
```
|
||||
|
||||
**When to Suppress:**
|
||||
- Non-sensitive cookies (theme preference, language)
|
||||
- HTTP-only development environments
|
||||
- Third-party analytics cookies
|
||||
|
||||
**Suppression Rule:**
|
||||
```tsv
|
||||
10054 https://example.com.* _ga|_gid|theme 614 WARN
|
||||
```
|
||||
|
||||
### 3. Cross-Domain JavaScript Source File Inclusion
|
||||
|
||||
**Alert:** JavaScript loaded from external domain
|
||||
|
||||
**False Positive Scenario:**
|
||||
- Legitimate CDN usage (jQuery, Bootstrap, etc.)
|
||||
- Third-party integrations (Google Analytics, Stripe)
|
||||
- Using Subresource Integrity (SRI)
|
||||
|
||||
**Verification:**
|
||||
```html
|
||||
<!-- Check if SRI is used -->
|
||||
<script src="https://cdn.example.com/library.js"
|
||||
integrity="sha384-HASH"
|
||||
crossorigin="anonymous"></script>
|
||||
```
|
||||
|
||||
**When to Suppress:**
|
||||
- CDN resources with SRI
|
||||
- Trusted third-party services
|
||||
- Company-owned CDN domains
|
||||
|
||||
**Suppression Rule:**
|
||||
```tsv
|
||||
10017 https://example.com/.* https://cdn.jsdelivr.net/.* 829 IGNORE
|
||||
```
|
||||
|
||||
### 4. Timestamp Disclosure
|
||||
|
||||
**Alert:** Unix timestamps found in response
|
||||
|
||||
**False Positive Scenario:**
|
||||
- Legitimate timestamp fields in API responses
|
||||
- Non-sensitive metadata
|
||||
- Public timestamps (post dates, etc.)
|
||||
|
||||
**Verification:**
|
||||
```json
|
||||
{
|
||||
"created_at": 1640995200, // Legitimate field
|
||||
"post_date": "2022-01-01"
|
||||
}
|
||||
```
|
||||
|
||||
**When to Suppress:**
|
||||
- API responses with datetime fields
|
||||
- Public-facing timestamps
|
||||
- Non-sensitive metadata
|
||||
|
||||
**Suppression Rule:**
|
||||
```tsv
|
||||
10096 https://api.example.com/.* created_at|updated_at 200 IGNORE
|
||||
```
|
||||
|
||||
### 5. Server Version Disclosure
|
||||
|
||||
**Alert:** Server version exposed in headers
|
||||
|
||||
**False Positive Scenario:**
|
||||
- Behind WAF/load balancer (version is of proxy, not app server)
|
||||
- Generic server headers
|
||||
- Already public knowledge
|
||||
|
||||
**Verification:**
|
||||
```bash
|
||||
curl -I https://example.com | grep Server
|
||||
# Check if version matches actual server
|
||||
```
|
||||
|
||||
**When to Suppress:**
|
||||
- Proxy/WAF version (not actual app server)
|
||||
- Generic headers without version numbers
|
||||
- When other compensating controls exist
|
||||
|
||||
**Suppression Rule:**
|
||||
```tsv
|
||||
10036 https://example.com.* .* 200 WARN
|
||||
```
|
||||
|
||||
## Verification Methodology
|
||||
|
||||
### Step 1: Understand the Alert
|
||||
|
||||
Review ZAP alert details:
|
||||
- **Description:** What is the potential vulnerability?
|
||||
- **Evidence:** What triggered the alert?
|
||||
- **CWE/OWASP Mapping:** What category does it fall under?
|
||||
- **Risk Level:** How severe is it?
|
||||
|
||||
### Step 2: Reproduce Manually
|
||||
|
||||
Attempt to exploit the vulnerability:
|
||||
|
||||
```bash
|
||||
# For XSS alerts
|
||||
curl "https://example.com/search?q=<script>alert(1)</script>"
|
||||
# Check if script is reflected unencoded
|
||||
|
||||
# For SQL injection alerts
|
||||
curl "https://example.com/api/user?id=1' OR '1'='1"
|
||||
# Check for SQL errors or unexpected behavior
|
||||
|
||||
# For path traversal alerts
|
||||
curl "https://example.com/download?file=../../etc/passwd"
|
||||
# Check if file is accessible
|
||||
```
|
||||
|
||||
### Step 3: Check Context
|
||||
|
||||
Consider the application context:
|
||||
- Is the functionality available to unauthenticated users?
|
||||
- Does it handle sensitive data?
|
||||
- Are there compensating controls (WAF, input validation)?
|
||||
|
||||
### Step 4: Document Decision
|
||||
|
||||
Create documentation for suppression decisions:
|
||||
|
||||
```markdown
|
||||
## Alert: SQL Injection in /api/user
|
||||
|
||||
**Decision:** False Positive
|
||||
|
||||
**Rationale:**
|
||||
- Endpoint requires authentication
|
||||
- Input is validated server-side (allowlist: 0-9 only)
|
||||
- WAF rule blocks SQL injection patterns
|
||||
- Manual testing confirmed no injection possible
|
||||
|
||||
**Suppressed:** Yes (Rule ID 40018, /api/user endpoint)
|
||||
|
||||
**Reviewed by:** security-team@example.com
|
||||
**Date:** 2024-01-15
|
||||
```
|
||||
|
||||
## Creating Suppression Rules
|
||||
|
||||
### Rules File Format
|
||||
|
||||
ZAP uses TSV (tab-separated values) format:
|
||||
|
||||
```
|
||||
alert_id URL_pattern parameter CWE_id action
|
||||
```
|
||||
|
||||
- **alert_id:** ZAP alert ID (e.g., 40018 for SQL Injection)
|
||||
- **URL_pattern:** Regex pattern for URL
|
||||
- **parameter:** Parameter name (or .* for all)
|
||||
- **CWE_id:** CWE identifier
|
||||
- **action:** IGNORE, WARN, or FAIL
|
||||
|
||||
### Example Rules File
|
||||
|
||||
`.zap/rules.tsv`:
|
||||
|
||||
```tsv
|
||||
# Suppress X-Content-Type-Options for CDN static content
|
||||
10021 https://cdn.example.com/static/.* .* 693 IGNORE
|
||||
|
||||
# Warn (don't fail) on analytics cookies without Secure flag
|
||||
10054 https://example.com/.* _ga|_gid 614 WARN
|
||||
|
||||
# Ignore timestamp disclosure in API responses
|
||||
10096 https://api.example.com/.* .* 200 IGNORE
|
||||
|
||||
# Ignore legitimate external JavaScript (with SRI)
|
||||
10017 https://example.com/.* https://cdn.jsdelivr.net/.* 829 IGNORE
|
||||
|
||||
# Suppress CSRF warnings for stateless API
|
||||
10202 https://api.example.com/.* .* 352 IGNORE
|
||||
```
|
||||
|
||||
### Using Rules File
|
||||
|
||||
```bash
|
||||
# Baseline scan with rules
|
||||
docker run -t zaproxy/zap-stable zap-baseline.py \
|
||||
-t https://example.com \
|
||||
-c .zap/rules.tsv \
|
||||
-r report.html
|
||||
|
||||
# Full scan with rules
|
||||
docker run -v $(pwd):/zap/wrk/:rw -t zaproxy/zap-stable zap-full-scan.py \
|
||||
-t https://example.com \
|
||||
-c /zap/wrk/.zap/rules.tsv \
|
||||
-r /zap/wrk/report.html
|
||||
```
|
||||
|
||||
## Custom Scan Policies
|
||||
|
||||
### Disable Entire Scan Rules
|
||||
|
||||
Create custom scan policy to disable problematic rules:
|
||||
|
||||
1. **Via ZAP GUI:**
|
||||
- Analyze > Scan Policy Manager
|
||||
- Create new policy
|
||||
- Disable specific rules
|
||||
- Export policy file
|
||||
|
||||
2. **Via Automation Framework:**
|
||||
|
||||
```yaml
|
||||
# zap_automation.yaml
|
||||
jobs:
|
||||
- type: activeScan
|
||||
parameters:
|
||||
policy: Custom-Policy
|
||||
rules:
|
||||
- id: 40018 # SQL Injection
|
||||
threshold: MEDIUM
|
||||
strength: HIGH
|
||||
- id: 10202 # CSRF
|
||||
threshold: OFF # Disable completely
|
||||
```
|
||||
|
||||
## Handling Different Alert Types
|
||||
|
||||
### High-Risk Alerts (Never Suppress Without Verification)
|
||||
|
||||
- SQL Injection
|
||||
- Command Injection
|
||||
- Remote Code Execution
|
||||
- Authentication Bypass
|
||||
- Server-Side Request Forgery (SSRF)
|
||||
|
||||
**Process:**
|
||||
1. Manual verification required
|
||||
2. Security team review
|
||||
3. Document compensating controls
|
||||
4. Re-test after fixes
|
||||
|
||||
### Medium-Risk Alerts (Contextual Suppression)
|
||||
|
||||
- XSS (if output is properly encoded)
|
||||
- CSRF (if tokens are implemented)
|
||||
- Missing headers (if compensating controls exist)
|
||||
|
||||
**Process:**
|
||||
1. Verify finding
|
||||
2. Check for compensating controls
|
||||
3. Document decision
|
||||
4. Suppress with WARN (not IGNORE)
|
||||
|
||||
### Low-Risk Alerts (Can Be Suppressed)
|
||||
|
||||
- Informational headers
|
||||
- Timestamp disclosure
|
||||
- Technology fingerprinting
|
||||
|
||||
**Process:**
|
||||
1. Quick verification
|
||||
2. Document reason
|
||||
3. Suppress with IGNORE
|
||||
|
||||
## Quality Assurance
|
||||
|
||||
### Review Suppression Rules Regularly
|
||||
|
||||
```bash
|
||||
# Monthly review checklist
|
||||
- [ ] Review all suppression rules for continued relevance
|
||||
- [ ] Check if suppressed issues have been fixed
|
||||
- [ ] Verify compensating controls are still in place
|
||||
- [ ] Update rules file with new false positives
|
||||
```
|
||||
|
||||
### Track Suppression Metrics
|
||||
|
||||
Monitor suppression trends:
|
||||
|
||||
```bash
|
||||
# Count suppressions by alert type
|
||||
grep -v '^#' .zap/rules.tsv | awk '{print $1}' | sort | uniq -c
|
||||
|
||||
# Alert if suppression count increases significantly
|
||||
```
|
||||
|
||||
### Peer Review Process
|
||||
|
||||
Require security team approval for suppressing high-risk alerts:
|
||||
|
||||
```yaml
|
||||
# .github/workflows/security-review.yml
|
||||
- name: Check for new suppressions
|
||||
run: |
|
||||
git diff origin/main .zap/rules.tsv > suppressions.diff
|
||||
if [ -s suppressions.diff ]; then
|
||||
echo "New suppressions require security team review"
|
||||
# Notify security team
|
||||
fi
|
||||
```
|
||||
|
||||
## Anti-Patterns to Avoid
|
||||
|
||||
### ❌ Don't Suppress Everything
|
||||
|
||||
Never create blanket suppression rules:
|
||||
|
||||
```tsv
|
||||
# BAD: Suppresses all XSS findings
|
||||
40012 .* .* 79 IGNORE
|
||||
```
|
||||
|
||||
### ❌ Don't Suppress Without Documentation
|
||||
|
||||
Always document why a finding is suppressed:
|
||||
|
||||
```tsv
|
||||
# BAD: No context
|
||||
10054 https://example.com/.* session_id 614 IGNORE
|
||||
|
||||
# GOOD: Documented reason
|
||||
# Session cookie is HTTPS-only in production; suppressing for staging environment
|
||||
10054 https://staging.example.com/.* session_id 614 IGNORE
|
||||
```
|
||||
|
||||
### ❌ Don't Ignore High-Risk Findings
|
||||
|
||||
Never suppress critical vulnerabilities without thorough investigation:
|
||||
|
||||
```tsv
|
||||
# DANGEROUS: Never suppress SQL injection without verification
|
||||
40018 https://example.com/.* .* 89 IGNORE
|
||||
```
|
||||
|
||||
## Tools and Scripts
|
||||
|
||||
### Analyze ZAP JSON Report
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import sys
|
||||
|
||||
with open('report.json') as f:
|
||||
report = json.load(f)
|
||||
|
||||
false_positives = []
|
||||
for site in report['site']:
|
||||
for alert in site['alerts']:
|
||||
if alert['risk'] in ['High', 'Medium']:
|
||||
print(f"{alert['alert']} - {alert['risk']}")
|
||||
print(f" URL: {alert['url']}")
|
||||
print(f" Evidence: {alert.get('evidence', 'N/A')}")
|
||||
print()
|
||||
```
|
||||
|
||||
### Generate Suppression Rules Template
|
||||
|
||||
```bash
|
||||
# Extract unique alert IDs from report
|
||||
jq -r '.site[].alerts[] | "\(.pluginid)\t\(.url)\t.*\t\(.cweid)\tWARN"' report.json \
|
||||
| sort -u > rules-template.tsv
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [ZAP Alert Details](https://www.zaproxy.org/docs/alerts/)
|
||||
- [ZAP Scan Rules](https://www.zaproxy.org/docs/docker/baseline-scan/)
|
||||
- [OWASP Testing Guide](https://owasp.org/www-project-web-security-testing-guide/)
|
||||
255
skills/appsec/dast-zap/references/owasp_mapping.md
Normal file
255
skills/appsec/dast-zap/references/owasp_mapping.md
Normal file
@@ -0,0 +1,255 @@
|
||||
# OWASP ZAP Alert Mapping to OWASP Top 10 2021 and CWE
|
||||
|
||||
This reference maps common OWASP ZAP alerts to OWASP Top 10 2021 categories and CWE (Common Weakness Enumeration) identifiers for compliance and reporting.
|
||||
|
||||
## OWASP Top 10 2021 Coverage
|
||||
|
||||
### A01:2021 - Broken Access Control
|
||||
|
||||
**ZAP Alerts:**
|
||||
- Path Traversal (CWE-22)
|
||||
- Directory Browsing (CWE-548)
|
||||
- Cross-Domain Misconfiguration (CWE-346)
|
||||
- Bypassing Access Controls (CWE-284)
|
||||
|
||||
**Risk Level:** High to Medium
|
||||
|
||||
**Remediation:**
|
||||
- Implement proper access control checks on server-side
|
||||
- Use allowlists for file access patterns
|
||||
- Disable directory listing
|
||||
- Enforce CORS policies strictly
|
||||
|
||||
### A02:2021 - Cryptographic Failures
|
||||
|
||||
**ZAP Alerts:**
|
||||
- Weak SSL/TLS Ciphers (CWE-327)
|
||||
- Cookie Without Secure Flag (CWE-614)
|
||||
- Password Autocomplete (CWE-522)
|
||||
- Sensitive Information in URL (CWE-598)
|
||||
|
||||
**Risk Level:** High to Medium
|
||||
|
||||
**Remediation:**
|
||||
- Use TLS 1.2+ with strong cipher suites
|
||||
- Set Secure and HttpOnly flags on all cookies
|
||||
- Disable autocomplete for sensitive fields
|
||||
- Never transmit sensitive data in URLs
|
||||
|
||||
### A03:2021 - Injection
|
||||
|
||||
**ZAP Alerts:**
|
||||
- SQL Injection (CWE-89)
|
||||
- Cross-Site Scripting (XSS) (CWE-79)
|
||||
- Command Injection (CWE-78)
|
||||
- LDAP Injection (CWE-90)
|
||||
- XML Injection (CWE-91)
|
||||
- XPath Injection (CWE-643)
|
||||
|
||||
**Risk Level:** High
|
||||
|
||||
**Remediation:**
|
||||
- Use parameterized queries (prepared statements)
|
||||
- Implement context-aware output encoding
|
||||
- Validate and sanitize all user input
|
||||
- Use allowlists for input validation
|
||||
- Implement Content Security Policy (CSP)
|
||||
|
||||
### A04:2021 - Insecure Design
|
||||
|
||||
**ZAP Alerts:**
|
||||
- Application Error Disclosure (CWE-209)
|
||||
- Insufficient Anti-automation (CWE-799)
|
||||
- Missing Rate Limiting
|
||||
|
||||
**Risk Level:** Medium to Low
|
||||
|
||||
**Remediation:**
|
||||
- Implement proper error handling (generic error messages)
|
||||
- Add CAPTCHA or rate limiting for sensitive operations
|
||||
- Design security controls during architecture phase
|
||||
- Implement anti-automation measures
|
||||
|
||||
### A05:2021 - Security Misconfiguration
|
||||
|
||||
**ZAP Alerts:**
|
||||
- Missing Security Headers (CWE-693)
|
||||
- X-Content-Type-Options
|
||||
- X-Frame-Options (CWE-1021)
|
||||
- Content-Security-Policy
|
||||
- Strict-Transport-Security (HSTS)
|
||||
- Server Leaks Information (CWE-200)
|
||||
- Default Credentials
|
||||
- Unnecessary HTTP Methods Enabled (CWE-650)
|
||||
|
||||
**Risk Level:** Medium to Low
|
||||
|
||||
**Remediation:**
|
||||
- Configure all security headers properly
|
||||
- Remove server version headers
|
||||
- Disable unnecessary HTTP methods (PUT, DELETE, TRACE)
|
||||
- Change default credentials
|
||||
- Implement minimal privilege principle
|
||||
|
||||
### A06:2021 - Vulnerable and Outdated Components
|
||||
|
||||
**ZAP Alerts:**
|
||||
- Outdated Software Version Detected
|
||||
- Known Vulnerable Components (requires integration with CVE databases)
|
||||
|
||||
**Risk Level:** High to Medium
|
||||
|
||||
**Remediation:**
|
||||
- Maintain software inventory
|
||||
- Regularly update dependencies and libraries
|
||||
- Subscribe to security advisories
|
||||
- Use dependency scanning tools (OWASP Dependency-Check, Snyk)
|
||||
|
||||
### A07:2021 - Identification and Authentication Failures
|
||||
|
||||
**ZAP Alerts:**
|
||||
- Weak Authentication (CWE-287)
|
||||
- Session Fixation (CWE-384)
|
||||
- Session ID in URL Rewrite (CWE-598)
|
||||
- Cookie No HttpOnly Flag (CWE-1004)
|
||||
- Credential Enumeration (CWE-209)
|
||||
|
||||
**Risk Level:** High
|
||||
|
||||
**Remediation:**
|
||||
- Implement multi-factor authentication (MFA)
|
||||
- Use secure session management
|
||||
- Regenerate session IDs after login
|
||||
- Set HttpOnly and Secure flags on session cookies
|
||||
- Implement account lockout mechanisms
|
||||
- Use generic error messages for authentication failures
|
||||
|
||||
### A08:2021 - Software and Data Integrity Failures
|
||||
|
||||
**ZAP Alerts:**
|
||||
- Missing Subresource Integrity (SRI) (CWE-353)
|
||||
- Insecure Deserialization (CWE-502)
|
||||
|
||||
**Risk Level:** High to Medium
|
||||
|
||||
**Remediation:**
|
||||
- Implement Subresource Integrity for CDN resources
|
||||
- Avoid deserializing untrusted data
|
||||
- Use digital signatures for critical data
|
||||
- Implement integrity checks
|
||||
|
||||
### A09:2021 - Security Logging and Monitoring Failures
|
||||
|
||||
**ZAP Alerts:**
|
||||
- Authentication attempts not logged
|
||||
- No monitoring of security events
|
||||
|
||||
**Risk Level:** Low (detection issue, not vulnerability)
|
||||
|
||||
**Remediation:**
|
||||
- Log all authentication attempts
|
||||
- Monitor for security anomalies
|
||||
- Implement centralized logging
|
||||
- Set up alerts for suspicious activities
|
||||
|
||||
### A10:2021 - Server-Side Request Forgery (SSRF)
|
||||
|
||||
**ZAP Alerts:**
|
||||
- Server-Side Request Forgery (CWE-918)
|
||||
- External Redirect (CWE-601)
|
||||
|
||||
**Risk Level:** High
|
||||
|
||||
**Remediation:**
|
||||
- Validate and sanitize all URLs
|
||||
- Use allowlists for allowed domains
|
||||
- Disable unnecessary URL schemas (file://, gopher://)
|
||||
- Implement network segmentation
|
||||
|
||||
## ZAP Alert ID to OWASP/CWE Quick Reference
|
||||
|
||||
| Alert ID | Alert Name | OWASP 2021 | CWE | Risk |
|
||||
|----------|-----------|------------|-----|------|
|
||||
| 40018 | SQL Injection | A03 | CWE-89 | High |
|
||||
| 40012 | Cross-Site Scripting (Reflected) | A03 | CWE-79 | High |
|
||||
| 40014 | Cross-Site Scripting (Persistent) | A03 | CWE-79 | High |
|
||||
| 40013 | Cross-Site Scripting (DOM) | A03 | CWE-79 | High |
|
||||
| 6 | Path Traversal | A01 | CWE-22 | High |
|
||||
| 7 | Remote File Inclusion | A01 | CWE-98 | High |
|
||||
| 90019 | Server-Side Code Injection | A03 | CWE-94 | High |
|
||||
| 90020 | Remote OS Command Injection | A03 | CWE-78 | High |
|
||||
| 90033 | Loosely Scoped Cookie | A07 | CWE-565 | Medium |
|
||||
| 10021 | X-Content-Type-Options Missing | A05 | CWE-693 | Low |
|
||||
| 10020 | X-Frame-Options Missing | A05 | CWE-1021 | Medium |
|
||||
| 10038 | Content Security Policy Missing | A05 | CWE-693 | Medium |
|
||||
| 10035 | Strict-Transport-Security Missing | A05 | CWE-319 | Low |
|
||||
| 10054 | Cookie Without Secure Flag | A02 | CWE-614 | Medium |
|
||||
| 10010 | Cookie No HttpOnly Flag | A07 | CWE-1004 | Medium |
|
||||
| 10098 | Cross-Domain Misconfiguration | A01 | CWE-346 | Medium |
|
||||
| 10055 | CSP Scanner: Wildcard Directive | A05 | CWE-693 | Medium |
|
||||
| 10096 | Timestamp Disclosure | A05 | CWE-200 | Low |
|
||||
| 10049 | Weak Authentication Method | A07 | CWE-287 | Medium |
|
||||
| 40029 | Server-Side Request Forgery | A10 | CWE-918 | High |
|
||||
|
||||
## Risk Level Priority Matrix
|
||||
|
||||
### High Risk (Immediate Action Required)
|
||||
- SQL Injection
|
||||
- Remote Code Execution
|
||||
- Authentication Bypass
|
||||
- SSRF
|
||||
- XXE (XML External Entity)
|
||||
|
||||
### Medium Risk (Fix in Current Sprint)
|
||||
- XSS (Cross-Site Scripting)
|
||||
- CSRF (Cross-Site Request Forgery)
|
||||
- Missing Security Headers (CSP, X-Frame-Options)
|
||||
- Insecure Cookie Configuration
|
||||
- Path Traversal (with limited impact)
|
||||
|
||||
### Low Risk (Fix in Backlog)
|
||||
- Information Disclosure (version headers)
|
||||
- Missing Informational Headers
|
||||
- Timestamp Disclosure
|
||||
- Autocomplete on Form Fields
|
||||
|
||||
### Informational (Documentation/Awareness)
|
||||
- Server Technology Disclosure
|
||||
- Application Error Messages
|
||||
- Charset Mismatch
|
||||
|
||||
## Compliance Mapping
|
||||
|
||||
### PCI-DSS 3.2.1
|
||||
- **Requirement 6.5.1** (Injection): SQL Injection, Command Injection, XSS
|
||||
- **Requirement 6.5.3** (Insecure Cryptography): Weak SSL/TLS, Insecure Cookies
|
||||
- **Requirement 6.5.7** (XSS): All XSS variants
|
||||
- **Requirement 6.5.8** (Access Control): Path Traversal, Broken Access Control
|
||||
- **Requirement 6.5.10** (Authentication): Weak Authentication, Session Management
|
||||
|
||||
### NIST 800-53
|
||||
- **AC-3** (Access Enforcement): Path Traversal, Authorization Issues
|
||||
- **IA-5** (Authenticator Management): Weak Authentication
|
||||
- **SC-8** (Transmission Confidentiality): Missing HTTPS, Weak TLS
|
||||
- **SI-10** (Information Input Validation): All Injection Flaws
|
||||
|
||||
### GDPR
|
||||
- **Article 32** (Security of Processing): All High/Medium findings affecting data security
|
||||
- **Article 25** (Data Protection by Design): Security Misconfigurations
|
||||
|
||||
## Usage in Reports
|
||||
|
||||
When generating compliance reports, reference this mapping to:
|
||||
|
||||
1. **Categorize findings** by OWASP Top 10 category
|
||||
2. **Assign CWE IDs** for standardized vulnerability classification
|
||||
3. **Map to compliance requirements** for audit trails
|
||||
4. **Prioritize remediation** based on risk level and compliance impact
|
||||
5. **Track metrics** by OWASP category over time
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [OWASP Top 10 2021](https://owasp.org/Top10/)
|
||||
- [CWE Top 25](https://cwe.mitre.org/top25/)
|
||||
- [ZAP Alert Details](https://www.zaproxy.org/docs/alerts/)
|
||||
- [OWASP Testing Guide](https://owasp.org/www-project-web-security-testing-guide/)
|
||||
Reference in New Issue
Block a user