Used to attribute the entry vector — which installed plugin/theme/core version is in a known vulnerable range — and to flag components that must be updated. This is enrichment: core malware detection never depends on it. If no key is configured, the skill skips it and says so.
- The Wordfence Intelligence Vulnerability Data Feed is free for personal and commercial use.
- Since 2026-03-09, the current (v3) feed requires a free API key (register a free Wordfence
account and generate a key). Older unauthenticated v2 endpoints now return
410 Gone. - No usage cap for reasonable consumption; Wordfence asks you to cache and not hammer the feed. This client caches for 6 hours by default.
- Create a free account at https://www.wordfence.com/.
- Generate a Vulnerability Data Feed API key in your account.
- Export it:
export WORDFENCE_API_KEY=your_free_key - (Optional) If the endpoint path changes in a future version, override it:
The current endpoints are documented at https://www.wordfence.com/help/wordfence-intelligence/ (see the "V3: Accessing and Consuming the Vulnerability Data Feed" page).
export WORDFENCE_FEED_URL="https://www.wordfence.com/api/intelligence/v3/vulnerabilities/scanner"
- scanner — minimal, detection-focused (affected software + version ranges). Default; best for version matching.
- production — fully analysed records with descriptions, CVSS, remediation. Richer report text.
# 1. Produce the installed-components list (via your gateway)
wp plugin list --fields=name,version,status --format=json > installed_plugins.json
wp theme list --fields=name,version,status --format=json > installed_themes.json
# (name == slug; the client accepts wp-cli's shape directly and defaults type=plugin)
# 2. Match against the feed
python3 scripts/wordfence_client.py --installed installed_plugins.json --json vulns.json
python3 scripts/wordfence_client.py --installed installed_themes.json --feed production
# just refresh the cache
python3 scripts/wordfence_client.py --refreshOutput ranks matches by CVSS and prints, per vulnerable component: type/slug, installed version, CVE, title, and the version to update to. Feed these into Layer 12 attribution: an installed component with an RCE / auth-bypass / arbitrary-file-upload CVE in range, plus a matching POST in the access logs at the breach minute, is a confirmed entry vector.
- The client sends the key both as
?apiKey=and as aBearerheader to be robust to the exact v3 auth scheme; adjust in one place (get_feed) if the connected feed differs. - Version-range matching handles pre-release suffixes (
-beta,-rc) and inclusive/exclusive bounds. - Also flag abandoned/closed plugins (removed from wordpress.org) — no patch will ever come; the recommendation is removal or replacement.
- Absence of a matching CVE does not mean the site is safe — it means the entry wasn't a known plugin vuln. Stolen credentials (the seed incident) leave no CVE; Layer 12 log analysis is what distinguishes the two.