WPScan 4.0.0: We’re Back

WPScan 4.0.0 is here.

We read through years of community issues. We addressed every major complaint. 75+ open issues → 0. Explicit scan control. Authentication‑based enumeration. Real‑time streaming. Consolidated codebase.

This is WPScan shaped by what you asked for.

You Control What Gets Scanned

The #1 complaint: WPScan scanned plugins automatically, burning API requests and time you didn’t want to spend.

Now it doesn’t. By default, WPScan checks WordPress version, active theme, and security findings. Nothing else. Want plugins? Add ‑e ap. Want everything? Tell it what you want.

# 4.0 default: minimal scan
wpscan --url example.com
# Explicit vulnerable plugin scan
wpscan --url example.com -e vp
# For passive-only scanning (closer to old 3.x default behavior)
wpscan --url example.com -e ap --plugins-detection passive

Your scan. Your rules.

Authentication-Based Scanning

Traditional scanners guess what’s installed by checking URLs and fingerprints. They miss things.

--wp‑auth changes that. Give WPScan a WordPress Application Password, and it queries the REST API directly for the authoritative list of every plugin and theme (active or inactive). Zero guessing. Zero false negatives.

wpscan --url example.com --wp-auth admin:"xxxxxxx"

Generate Application Passwords at Users → Profile → Application Passwords in wp‑admin.

Real-Time Results

Long scans suck when you’re waiting for output. --format jsonl streams findings as they’re discovered. Pipe to jq, monitor in real‑time, integrate with your tools.

# See results as they arrive
wpscan --url example.com -e ap --format jsonl | jq .

Resume Failed Attacks

Brute force attacks take hours. Network glitches shouldn’t mean starting over.

# Resume at line 5000
wpscan --url example.com -P wordlist.txt --wordlist-skip 5000

# Auto-retry failed requests
wpscan --url example.com -P wordlist.txt --max-retries 3

Everything Else

  • Better context: active install counts, last updated dates, PoC links
  • Better errors: clearer messages, helpful links, diagnostic info
  • Better flexibility: --follow‑redirect, --proxy‑target‑only--exclude‑vulns
  • Better visibility: audit trails, HTTP status tracking
  • SAML support: --expect‑saml for SAML‑authenticated sites
  • Backup enumeration: ‑e bf finds backup folders

Full changelog

Breaking Changes

Ruby 3.3+ required (Ruby 4.0 supported). Upgrade before installing 4.0.0.

Default enumeration changed. Plugins and config backups no longer auto‑scan. Use ‑e explicitly.

Detection mode options removed. --config‑backups‑detection, --db‑exports‑detection, --medias‑detection, --timthumbs‑detection are gone (they never worked properly anyway).

XDG directories. Database goes to $XDG_CACHE_HOME/wpscan/db (or ~/.cache/wpscan/db if not set), config to $XDG_CONFIG_HOME/wpscan/ (or ~/.config/wpscan/ if not set). Existing installs keep using ~/.wpscan/.

Built to Last

This isn’t just a cleanup release. We’re setting WPScan up for sustained maintenance:

  • Three repos → one: cms_scanner and opt_parse_validator are now part of wpscan. No more coordinated multi‑repo PRs.
  • Comprehensive tests: 8.5k+ lines migrated, E2E tests added, skipped tests implemented
  • Modern CI/CD: faster builds, better coverage, security scanning
  • One place to contribute: clearer architecture, easier onboarding

Get It

# Upgrade (if already installed)
gem update wpscan
# Or via Homebrew
brew upgrade wpscan

# Fresh install
gem install wpscan
# Or via Homebrew
brew tap wpscanteam/tap && brew install wpscan

# Docker
docker pull wpscanteam/wpscan:latest

For complete installation instructions, including system dependencies, see the README.

Get Involved

We’re back and actively maintaining WPScan. Here’s how to get involved:

Found a bug? Open an issue

Have a feature request? Start a discussion or open an issue

Want to contribute? Pull requests welcome – the codebase is cleaner and easier to contribute to than ever

Posted by

Get News and Tips From WPScan