Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 17:51:02 +08:00
commit ff1f4bd119
252 changed files with 72682 additions and 0 deletions

View 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/)