Install
Pick whichever fits — see the full install matrix.
# Windows (winget)
winget install Bryan.WPSecScan
# macOS / Linux (pip)
pip install wpsecscan
# Docker
docker run --rm ghcr.io/bryanflowers/wpsecscan:2.3.0 --help First scan
# Walk every check with a synthetic site
wpsecscan --demo
# Pull the latest CVE feed (8 sources, deduped)
wpsecscan db update
# Scan your site (passive checks only by default)
wpsecscan scan https://your-site.com
# Save the report
wpsecscan scan https://your-site.com --out report.html --format html Aggressive mode
33 of the 189 checks send active payloads (SQLi probes, XSS reflections,
SSRF, etc.). They're off by default. Opt-in with --aggressive.
Active exploit verification needs a stricter consent gate:
WPSECSCAN_OWNED_TARGETS=1 AND the target
must be in your sites list (~/.wpsecscan/sites.json).
wpsecscan scan https://your-site.com --aggressive
# Active PoC verification (stricter consent)
WPSECSCAN_OWNED_TARGETS=1 wpsecscan scan https://your-site.com \
--aggressive --verify-exploits Report formats
12 built-in formats:
- html · interactive single-page
- pdf · executive report (needs
[pdf]extra) - json · machine-readable
- csv · spreadsheet-friendly
- xlsx · Excel
- md · GitHub-flavored Markdown
- sarif · for code-scanning UIs
- cyclonedx · SBOM-compatible
- badge · SVG shield
- burp · Burp Suite import
- zap · OWASP ZAP import
- eli5 · plain-English exec summary
Daemon mode
REST API for the GUI, mobile, and SDK clients.
wpsecscan daemon --config daemon.yaml
# OpenAPI 3.1 spec: github.com/bryanflowers/wpsecscan/blob/main/openapi/wpsecscan-api.yaml Scheduled scans
wpsecscan sites add example --url https://example.com
wpsecscan schedule add example --cron "0 2 * * *"
wpsecscan schedule list
wpsecscan digest weekly Companion plugin
For server-side checks (MFA audit, DB triggers, wp-cron jobs, webhook inventory): install wpsecscan-companion.zip in your WP admin → Plugins → Upload Plugin. Generate a shared secret in plugin settings, then store it in WPSecScan:
wpsecscan sites add example --url https://example.com \
--companion-token sk_xxx AI options (opt-in)
10 AI-assisted features behind an opt-in panel. All off by default. Require an LLM key (OpenAI / Anthropic / Ollama). PII masking on by default.
export OPENAI_API_KEY=sk-...
wpsecscan ai-options list
wpsecscan ai-options set severity_auto_tuner true
wpsecscan ai-options set exec_brief_audience cto
# Or via GUI: Tools → Advanced AI options... Usage analytics (opt-in, local-first)
Off by default. Local-only by default (events never leave your machine unless you also set an upload URL). Per-event field allowlist prevents PII leaks.
wpsecscan analytics enable
wpsecscan analytics show 50 # inspect last 50 events
wpsecscan analytics export out.jsonl
wpsecscan analytics forget # delete everything locally Full doc: docs/analytics.md.
Enterprise mode
Self-hostable. Same codebase as the OSS scanner — no separate fork. Includes OIDC + SAML SSO, RBAC, HMAC-chained audit log, two-person sign-off for aggressive scans, multi-tenant namespacing, per-tenant quotas, Stripe metered-billing scaffold.
See
wpsecscan/auth/,
wpsecscan/enterprise/, and
docs/api-reference.md.
Integrations
Windows Defender false-positive
Defender may flag wpsecscan.exe on first run. It's a known
false-positive because the binary contains string-pattern signatures
for webshells (so we can detect them in your site). The .exe is
Sigstore-signed; verify the signature to confirm authenticity.
Workaround: add an exclusion via Tools → Add Windows Defender exclusion... in the GUI, or run the PowerShell helper:
Add-MpPreference -ExclusionPath "C:\Tools\wpsecscan.exe" Writing a check
Drop a .py module in ~/.wpsecscan/plugins/
or contribute one upstream. The scaffolder generates a skeleton:
python scripts/new-check.py --id my_check
python scripts/lint-checks.py # enforce hygiene Full tutorial: docs/writing-a-check.md.