Files
2025-11-29 17:51:02 +08:00

12 KiB

Nuclei False Positive Handling Guide

Table of Contents

Understanding False Positives

False positives occur when Nuclei reports a finding that doesn't represent an actual security vulnerability in the context of your application.

Types of False Positives

  1. Context-Specific: Finding is valid in general but not applicable to your application
  2. Version-Specific: CVE template triggers but your version is patched
  3. Configuration-Based: Security control exists but Nuclei can't detect it
  4. Pattern Matching Errors: Regex/word matchers trigger on benign content

Common False Positive Scenarios

1. Missing Security Headers (Info/Low Severity)

Finding: Missing X-Frame-Options, Content-Security-Policy

False Positive When:

  • Headers set at CDN/WAF level (not visible to scanner)
  • Application is not intended for browser rendering (pure API)
  • Modern browsers already protect against clickjacking

Verification:

# Check headers from actual browser
curl -I https://target-app.com
curl -I https://target-app.com -H "User-Agent: Mozilla/5.0"

# Check if CDN adds headers
curl -I https://target-app.com -v 2>&1 | grep -i "x-frame-options\|content-security"

Filter Strategy:

# Exclude header-related info findings
nuclei -u https://target-app.com -etags headers -severity critical,high

2. Directory Listing / Exposed Paths

Finding: Directory listing enabled, exposed paths like /admin, /backup

False Positive When:

  • Path requires authentication (Nuclei tested unauthenticated)
  • Path is intentionally public (documentation, public assets)
  • CDN/WAF blocks access (returns 200 with error page)

Verification:

# Manual verification with authentication
curl https://target-app.com/admin \
  -H "Authorization: Bearer $TOKEN" \
  -H "Cookie: session=$SESSION"

# Check actual response content
curl https://target-app.com/backup | head -20

Filter Strategy:

# Exclude exposure templates for authenticated scans
nuclei -u https://target-app.com \
  -header "Authorization: Bearer $TOKEN" \
  -etags exposure

3. CVE Templates Against Patched Versions

Finding: CVE-2024-XXXXX detected

False Positive When:

  • Application version is patched but template matches on generic patterns
  • Backported patches applied without version number change
  • Template uses loose detection criteria

Verification:

# Check actual version
curl https://target-app.com/version
curl https://target-app.com -v 2>&1 | grep -i "server:"

# Cross-reference with CVE details
# Check if version is vulnerable per NVD/vendor advisory

Filter Strategy:

# Scan only recent CVEs
nuclei -u https://target-app.com \
  -tags cve \
  -template-condition "contains(id, 'CVE-2024') || contains(id, 'CVE-2023')"

# Exclude specific false positive templates
nuclei -u https://target-app.com \
  -exclude-id CVE-2018-12345,CVE-2019-67890

4. Technology Detection False Positives

Finding: WordPress, Drupal, or other CMS detected

False Positive When:

  • Generic strings match (like "wp-" in custom code)
  • Legacy migration artifacts remain
  • Application mimics CMS structure but isn't actually that CMS

Verification:

# Check for actual CMS files
curl https://target-app.com/wp-admin/
curl https://target-app.com/wp-includes/
curl https://target-app.com/readme.html

# Technology fingerprinting
whatweb https://target-app.com
wappalyzer https://target-app.com

Filter Strategy:

# Exclude tech detection templates
nuclei -u https://target-app.com -etags tech

5. Default Login Pages

Finding: Admin panel or login page detected

False Positive When:

  • Panel is legitimate and intended to be accessible
  • Panel requires MFA even if default credentials work
  • Detection based on title/strings only without credential testing

Verification:

# Test if default credentials actually work
curl -X POST https://target-app.com/login \
  -d "username=admin&password=admin" \
  -v

# Check if MFA is required
curl -X POST https://target-app.com/login \
  -d "username=admin&password=admin" \
  -c cookies.txt

curl https://target-app.com/dashboard \
  -b cookies.txt

Filter Strategy:

# Scan with authentication to skip login detection
nuclei -u https://target-app.com \
  -header "Authorization: Bearer $TOKEN" \
  -etags default-logins,exposed-panels

6. API Endpoints Reporting Errors

Finding: SQL errors, stack traces, or verbose errors detected

False Positive When:

  • Errors are intentional validation messages
  • Stack traces only shown in dev/staging (not production)
  • API returns structured error JSON (not actual stack trace)

Verification:

# Check actual error response
curl https://api.target.com/endpoint?id=invalid -v

# Verify it's not SQL error but validation error
curl https://api.target.com/endpoint?id=' OR '1'='1 -v

7. CORS Misconfiguration

Finding: Access-Control-Allow-Origin: *

False Positive When:

  • Intentional for public APIs
  • Only applies to non-sensitive endpoints
  • Additional CORS headers restrict actual access

Verification:

# Check if sensitive endpoints have CORS
curl https://api.target.com/public/data \
  -H "Origin: https://evil.com" -v

curl https://api.target.com/private/users \
  -H "Origin: https://evil.com" \
  -H "Authorization: Bearer $TOKEN" -v

Verification Techniques

Manual Verification Checklist

For each critical/high severity finding:

  1. Reproduce the finding:

    # Use exact URL and parameters from Nuclei output
    curl "https://target-app.com/vulnerable-path" -v
    
  2. Check authentication context:

    # Test with authentication
    curl "https://target-app.com/vulnerable-path" \
      -H "Authorization: Bearer $TOKEN" -v
    
  3. Verify exploitability:

    • Can you actually exploit the vulnerability?
    • Is there a working PoC?
    • What's the actual impact?
  4. Check mitigating controls:

    • WAF rules blocking exploitation
    • Network segmentation limiting access
    • Monitoring and alerting in place
  5. Consult security team:

    • Discuss edge cases with security engineers
    • Review against threat model

Automated Verification Script

Use bundled script to batch verify findings:

python3 scripts/verify_findings.py \
  --input nuclei-results.jsonl \
  --auth-token $AUTH_TOKEN \
  --output verified-findings.jsonl

Template Filtering Strategies

Strategy 1: Severity-Based Filtering

Focus on high-impact findings:

# Critical and high only
nuclei -u https://target-app.com -severity critical,high

# Exclude info findings
nuclei -u https://target-app.com -exclude-severity info

Strategy 2: Tag-Based Filtering

Filter by vulnerability type:

# Only CVEs and OWASP vulnerabilities
nuclei -u https://target-app.com -tags cve,owasp

# Exclude informational tags
nuclei -u https://target-app.com -etags tech,info,headers

Strategy 3: Template Exclusion

Exclude known false positive templates:

# Exclude specific templates
nuclei -u https://target-app.com \
  -exclude-id CVE-2018-12345,generic-login-panel

# Exclude template directories
nuclei -u https://target-app.com \
  -exclude-templates nuclei-templates/http/misconfiguration/

Strategy 4: Custom Template Allowlist

Use only verified templates:

# Scan with curated template set
nuclei -u https://target-app.com \
  -t custom-templates/verified/ \
  -t nuclei-templates/http/cves/2024/

Strategy 5: Conditional Template Execution

Use template conditions:

# Only recent critical CVEs
nuclei -u https://target-app.com \
  -tags cve \
  -severity critical \
  -template-condition "contains(id, 'CVE-2024')"

Custom Template Refinement

Improving Matcher Accuracy

Before (High False Positives):

matchers:
  - type: word
    words:
      - "admin"

After (Lower False Positives):

matchers-condition: and
matchers:
  - type: status
    status:
      - 200

  - type: word
    part: body
    words:
      - "admin"
      - "dashboard"
      - "login"
    condition: and

  - type: regex
    regex:
      - '<title>[^<]*admin[^<]*panel[^<]*</title>'
    case-insensitive: true

Adding Negative Matchers

Exclude known false positive patterns:

matchers:
  - type: word
    words:
      - "SQL syntax error"

  # Negative matcher - must NOT match
  - type: word
    negative: true
    words:
      - "validation error"
      - "input error"

Version-Specific Matching

Match specific vulnerable versions:

matchers-condition: and
matchers:
  - type: regex
    regex:
      - 'WordPress/([0-5]\.[0-9]\.[0-9])'  # Versions < 6.0.0

  - type: word
    words:
      - "wp-admin"

Confidence-Based Classification

Add confidence levels to findings:

info:
  metadata:
    confidence: high  # low, medium, high

matchers-condition: and  # More matchers = higher confidence
matchers:
  - type: status
    status: [200]

  - type: word
    words: ["vulnerable_signature_1", "vulnerable_signature_2"]
    condition: and

  - type: regex
    regex: ['specific[_-]pattern']

False Positive Tracking

Document Known False Positives

Create suppression file:

# false-positives.yaml
suppressions:
  - template: CVE-2018-12345
    reason: "Application version is patched (backport applied)"
    verified_by: security-team
    verified_date: 2024-11-20

  - template: exposed-admin-panel
    urls:
      - https://target-app.com/admin
    reason: "Admin panel requires MFA and IP allowlist"
    verified_by: security-team
    verified_date: 2024-11-20

  - template: missing-csp-header
    reason: "CSP header added at CDN level (Cloudflare)"
    verified_by: devops-team
    verified_date: 2024-11-20

Use Suppression in Scans

# Filter out documented false positives
python3 scripts/filter_suppressions.py \
  --scan-results nuclei-results.jsonl \
  --suppressions false-positives.yaml \
  --output filtered-results.jsonl

Best Practices

  1. Always Verify Critical Findings Manually: Don't trust automated tools blindly
  2. Context Matters: What's vulnerable in one app may be safe in another
  3. Track False Positives: Document and share with team
  4. Refine Templates: Improve matcher accuracy over time
  5. Use Multiple Tools: Cross-verify with other scanners (ZAP, Burp, etc.)
  6. Severity Calibration: Adjust severity based on your environment
  7. Regular Template Updates: Keep templates current to reduce false positives
  8. Authenticated Scanning: Many false positives occur in unauthenticated scans

Tools and Resources

Verification Tools

# cURL for manual verification
curl -v https://target-app.com/endpoint

# httpie (user-friendly HTTP client)
http https://target-app.com/endpoint

# Burp Suite for manual testing
# ZAP for cross-verification

Analysis Scripts

Use bundled scripts:

# Compare findings across scans
python3 scripts/compare_scans.py \
  --baseline scan1.jsonl \
  --current scan2.jsonl

# Filter findings by confidence
python3 scripts/filter_by_confidence.py \
  --input scan-results.jsonl \
  --min-confidence high \
  --output high-confidence.jsonl

Conclusion

False positives are inevitable in automated security scanning. The key is to:

  • Understand WHY false positives occur
  • Develop systematic verification processes
  • Refine templates and filters over time
  • Document and track false positives for future reference
  • Balance automation with manual verification

A good rule of thumb: Spend time refining your scanning approach to maximize signal-to-noise ratio.