How to Run Security Scans¶
Multi-tier security scanning with Python-native checks, Nuclei templates, OWASP ZAP DAST, and AI-powered finding analysis with remediation planning.
Overview¶
The security testing framework provides four scanner tiers:
| Tier | Tool | Speed | Depth | Use Case |
|---|---|---|---|---|
| Quick Scan | Python (httpx) | ~10-30s | Surface-level | Headers, cookies, SSL, CORS, info disclosure |
| Nuclei Scan | nuclei binary | ~1-5min | Template-based | Known CVEs, misconfigurations, tech detection |
| ZAP DAST | OWASP ZAP | ~5-30min | Deep | Spider + active scan, XSS, SQLi, CSRF |
| AI Analysis | Claude | ~1-2min | Contextual | Finding prioritization, remediation planning |
Additionally, passive mode lets functional Playwright tests proxy through ZAP for automatic security analysis during normal test runs.
Prerequisites¶
- Quorvex AI installed and running (
make devormake prod-dev) - For Nuclei scans:
nucleibinary installed (installation guide) - For ZAP scans: ZAP daemon running via Docker
- A target application to scan
Start ZAP Daemon (for ZAP and Full scans)¶
This starts ZAP as a daemon on port 8090.
Step-by-Step Usage¶
1. Create a Security Test Spec¶
Write a markdown spec describing what to scan:
# Security Test: Production API
## Target
https://api.example.com
## Scan Type
full
## Focus Areas
- Authentication endpoints
- API input validation
- CORS configuration
- Information disclosure
## Authentication
Bearer token: {{API_TOKEN}}
## Exclusions
- /health
- /docs
Save via the dashboard at /security-testing or the API:
curl -X POST http://localhost:8001/security-testing/specs \
-H "Content-Type: application/json" \
-d '{
"name": "production-api",
"content": "# Security Test: Production API\n...",
"project_id": "your-project-id"
}'
2. Run a Scan¶
Choose a scan tier based on your needs:
Quick Scan (fastest, no external tools needed):
curl -X POST http://localhost:8001/security-testing/scan/quick \
-H "Content-Type: application/json" \
-d '{"spec_name": "production-api", "project_id": "your-project-id"}'
Nuclei Scan (requires nuclei binary):
curl -X POST http://localhost:8001/security-testing/scan/nuclei \
-H "Content-Type: application/json" \
-d '{"spec_name": "production-api", "project_id": "your-project-id"}'
ZAP DAST Scan (requires ZAP daemon):
curl -X POST http://localhost:8001/security-testing/scan/zap \
-H "Content-Type: application/json" \
-d '{"spec_name": "production-api", "project_id": "your-project-id"}'
Full Scan (runs all tiers sequentially):
curl -X POST http://localhost:8001/security-testing/scan/full \
-H "Content-Type: application/json" \
-d '{"spec_name": "production-api", "project_id": "your-project-id"}'
All scans run as background jobs. Poll the status:
3. Review Findings¶
View findings from a scan run:
# All findings
curl http://localhost:8001/security-testing/runs/RUN_ID/findings
# Filter by severity
curl "http://localhost:8001/security-testing/runs/RUN_ID/findings?severity=high"
# Aggregated summary
curl http://localhost:8001/security-testing/findings/summary?project_id=your-project-id
Findings include severity levels: critical, high, medium, low, info.
4. Triage Findings¶
Update finding status as you review them:
curl -X PATCH http://localhost:8001/security-testing/findings/FINDING_ID/status \
-H "Content-Type: application/json" \
-d '{"status": "false_positive", "notes": "Expected behavior for this endpoint"}'
Available statuses: open, false_positive, fixed, accepted_risk.
5. AI Remediation Analysis¶
Get AI-powered analysis and remediation plan:
curl -X POST http://localhost:8001/security-testing/analyze/RUN_ID \
-H "Content-Type: application/json" \
-d '{"project_id": "your-project-id"}'
The AI analyzes all findings, prioritizes them by risk, and generates actionable remediation steps.
6. Generate Spec from Exploration¶
If you have run an AI exploration session, generate a security spec from the discovered endpoints:
curl -X POST http://localhost:8001/security-testing/generate-spec \
-H "Content-Type: application/json" \
-d '{"exploration_id": "SESSION_ID", "project_id": "your-project-id"}'
Passive Mode (ZAP Proxy)¶
When ZAP_PROXY_ENABLED=true, functional Playwright tests automatically proxy through ZAP. This means every UI test also performs passive security analysis -- detecting issues like missing security headers, insecure cookies, and information leaks without any extra configuration.
Enable in .env:
Configuration¶
| Variable | Default | Description |
|---|---|---|
ZAP_HOST | localhost | ZAP daemon host |
ZAP_PORT | 8090 | ZAP daemon port |
ZAP_API_KEY | -- | ZAP API key (optional) |
ZAP_PROXY_ENABLED | false | Enable passive mode |
NUCLEI_TIMEOUT_SECONDS | 600 | Nuclei scan timeout (10 min) |
SECURITY_SCAN_TIMEOUT | 1800 | Overall scan timeout (30 min) |
API Endpoints Reference¶
| Method | Path | Description |
|---|---|---|
| POST | /security-testing/specs | Create security spec |
| GET | /security-testing/specs | List specs |
| POST | /security-testing/scan/quick | Run quick scan |
| POST | /security-testing/scan/nuclei | Run Nuclei scan |
| POST | /security-testing/scan/zap | Run ZAP DAST scan |
| POST | /security-testing/scan/full | Run all tiers |
| GET | /security-testing/jobs/{job_id} | Poll job status |
| GET | /security-testing/runs | List scan history |
| GET | /security-testing/runs/{run_id} | Scan details |
| GET | /security-testing/runs/{run_id}/findings | Findings with filter |
| PATCH | /security-testing/findings/{id}/status | Update finding status |
| GET | /security-testing/findings/summary | Aggregated counts |
| POST | /security-testing/analyze/{run_id} | AI remediation analysis |
| POST | /security-testing/generate-spec | AI spec from exploration |
Key Files¶
| Path | Purpose |
|---|---|
orchestrator/api/security_testing.py | API endpoints |
orchestrator/services/security/quick_scanner.py | Python-native security checks |
orchestrator/services/security/nuclei_runner.py | Nuclei subprocess execution |
orchestrator/services/security/zap_client.py | ZAP API client wrapper |
orchestrator/services/security/finding_deduplicator.py | Cross-scanner dedup |
orchestrator/workflows/security_analyzer.py | AI analysis workflow |
.claude/agents/security-analyzer.md | AI agent prompt |
Quick Scan Checks¶
The quick scanner performs these Python-native checks:
- Security headers -- Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security, etc.
- Cookie security -- HttpOnly, Secure, SameSite flags
- SSL/TLS -- certificate validity, protocol version
- CORS -- overly permissive Access-Control-Allow-Origin
- Information disclosure -- server version headers, error page details, debug endpoints
Troubleshooting¶
| Problem | Solution |
|---|---|
| ZAP not reachable | Start with: docker compose --profile security up -d zap |
| Nuclei not found | Install: go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest |
| Scan timeout | Increase SECURITY_SCAN_TIMEOUT in .env |
| Duplicate findings across scanners | The finding_deduplicator.py handles this automatically |
| Passive mode not detecting issues | Verify ZAP_PROXY_ENABLED=true and ZAP daemon is running |
| AI analysis returns empty results | Check AI credentials in .env |
Verification¶
Confirm security testing works:
- Quick scan completes and returns findings (or "no issues found")
- Findings include severity levels and descriptions
- AI remediation analysis returns actionable recommendations
- Finding status updates persist (open, false_positive, fixed, accepted_risk)
- If using passive mode, running a UI test generates passive findings in ZAP
Related Guides¶
- API Testing -- functional API testing
- Load Testing -- performance testing
- Exploration and Requirements -- discover endpoints to scan
- Credential Management -- manage scan authentication