This is a dirty note slipped into the newsroom, not a skeleton key to the building
CVE-2025-22308 is a stored XSS flaw in the WordPress Smart Custom Fields plugin. Authoritative WordPress security sources track it as affecting versions through 5.0.0, with the fix in 5.0.1. In plain English: a user who already has at least Contributor access can plant script content into a page or field handled by the plugin, and that script runs later when someone views the poisoned content.
The vendor-style 6.5/MEDIUM baseline is technically defensible, but it overstates enterprise urgency. The real attack chain requires authenticated access first, then a more privileged victim to render the payload, which means this is usually a post-initial-access or abused low-privilege account problem, not a clean unauthenticated internet-edge compromise. The stored nature and site-level blast radius keep it from being ignored, but the attacker-position requirement pushes it down to LOW for most 10,000-host environments.
4 steps from start to impact.
Get a Contributor foothold
Burp Suite, credential stuffing kits, or stolen session cookies rather than a purpose-built exploit for this CVE.- Target runs WordPress with the Smart Custom Fields plugin installed and vulnerable
- Attacker has authenticated access at Contributor+ level
- The role can create or edit content that uses vulnerable field handling
- Most enterprise WordPress estates do not grant Contributor broadly
- SSO, MFA, and hardened admin workflows often stop the account-acquisition step
- Many corporate WordPress sites are brochureware with only a few trusted authors
Plant the stored payload
Burp Suite repeater/editor or raw browser DevTools; there is no evidence a specialized public exploit kit is required.- Attacker can submit content that reaches the vulnerable input/output path
- The application stores the malicious value without proper sanitization/escaping
- Payloads can break if the site uses additional sanitizers, editor restrictions, or custom output escaping
- Some deployments use the plugin only for narrowly scoped metadata that may never render in a privileged session
Wait for a privileged viewer
fetch() calls against wp-admin, admin-ajax.php, or REST endpoints.- A victim must load the poisoned content
- The victim session has privileges worth stealing or reusing
- This is user-interaction dependent; no victim view, no impact
- On mature sites, admins may rarely browse contributor drafts directly
- CSP, hardened cookies, and admin workflow separation can reduce post-XSS usefulness
admin-ajax/REST calls from an admin browser session.Abuse the admin session for site impact
- Victim has admin-like capability
- WordPress permissions and site settings allow sensitive actions from the browser session
- Blast radius is typically one WordPress site/tenant, not the wider enterprise
- Hardened estates often disable in-app file editing and tightly audit admin creation
- Many victims will be editors, not administrators
The supporting signals.
| In-the-wild status | No confirmed active exploitation found in KEV or the major public references reviewed. This appears to be a disclosed plugin bug, not a live campaign driver. |
|---|---|
| KEV status | Not in CISA KEV. CISA's Vulnrichment data for this record also marks exploitation as none. |
| Proof-of-concept availability | No mainstream public PoC located in reviewed search results or common references. *Inference:* weaponization is straightforward with generic XSS tradecraft, but there is no sign of broad packaged exploit tooling. |
| EPSS | 0.00152 from the user-supplied intel, which is extremely low. Third-party mirrors also show this CVE sitting in a low percentile band rather than the top exploit-likelihood cohort. |
| CVSS vector reality check | AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:L says the quiet part out loud: network reachable, yes—but only after login, and only if someone else views it. Those PR:L and UI:R requirements are the main downgrade pressure. |
| Affected versions | Smart Custom Fields <= 5.0.0. |
| Fixed version | 5.0.1 or later. Current WordPress.org listing is 5.0.7, so the fix has been available for multiple release cycles. |
| Exposure population | WordPress.org reports 50,000+ active installations for the plugin. That's broad plugin footprint, but not broad *exploitability* because most corporate WordPress sites do not expose Contributor workflows to the public internet. |
| Internet scanning / fingerprintability | There is no strong dedicated internet-wide fingerprint for this specific vulnerable condition in public exposure engines comparable to an edge appliance CVE. Operationally, exposure is tied to authenticated CMS workflows, not a stand-alone listening service. |
| Research / disclosure | Published 2025-01-06/2025-01-07 depending on source normalization; credited researcher: Robert DeVore. |
noisgate verdict.
The decisive factor is attacker position: this bug starts at authenticated Contributor access, which already implies either a weak author workflow or a prior foothold. Then it still needs a separate victim view, so real-world exploitation is gated twice before it becomes meaningful.
Why this verdict
- Start from vendor 6.5, then cut for
PR:L: requiring Contributor+ means this is not an internet-edge initial compromise; it already assumes account abuse or prior access. - Cut again for
UI:R: the payload still needs a privileged user to view the malicious content before it pays off. - Blast radius is usually one WordPress site: even when it works, this is typically a single-site/admin-session problem, not an estate-wide host compromise primitive.
Why not higher?
There is no evidence of KEV listing, no confirmed in-the-wild exploitation, no widely circulated public exploit, and no unauthenticated path. In enterprise terms, this is a workflow abuse bug inside a CMS, not a perimeter-break or mass-compromise event.
Why not lower?
Stored XSS in a CMS is still materially dangerous because it can turn a low-privilege author account into administrator-level actions if the victim path lands. The plugin also has 50,000+ active installs, so this is not an obscure one-off package with near-zero real-world footprint.
What to do — in priority order.
- Restrict authoring roles — Reduce or remove unnecessary Contributor accounts and disable public/self-registration where business permits. For a LOW verdict there is no mitigation SLA, so do this as backlog hygiene during your normal IAM and CMS cleanup cycle.
- Enforce MFA and SSO on WordPress admins and authors — This vulnerability is bottlenecked by authenticated access, so stronger identity controls shrink the reachable population fast. For a LOW verdict there is no mitigation SLA, so fold this into your standard WordPress hardening program rather than emergency change windows.
- Review content and admin activity logs — Look for unusual draft/post edits from low-privilege users followed by admin account changes, plugin setting changes, or suspicious
admin-ajaxactivity. For a LOW verdict there is no mitigation SLA, so add these checks to your regular detection content rather than spinning up an incident sprint. - Disable risky admin conveniences — Turn off in-dashboard plugin/theme editing and keep privileged browser usage segmented from everyday browsing. This limits post-XSS payoff if an admin does render a poisoned page; for LOW, implement during routine hardening with no special SLA.
- A perimeter firewall alone does not solve this, because the malicious input is submitted through legitimate authenticated WordPress workflows.
- External network vulnerability scanning will not tell you whether your role model makes this exploitable; version detection without role/context is only half the picture.
- Focusing only on anonymous front-end traffic misses the real problem, because the dangerous execution often happens in an authenticated admin/editor browser session.
Crowdsourced verification payload.
Run this on the WordPress host or in a container with the plugin files mounted. Invoke it as bash verify-scf-cve-2025-22308.sh /var/www/html or point directly at the plugin directory; no root is required if the web files are readable. It checks the installed smart-custom-fields version and reports VULNERABLE, PATCHED, or UNKNOWN.
#!/usr/bin/env bash
# verify-scf-cve-2025-22308.sh
# Check whether WordPress Smart Custom Fields is vulnerable to CVE-2025-22308
# Usage:
# bash verify-scf-cve-2025-22308.sh /var/www/html
# bash verify-scf-cve-2025-22308.sh /var/www/html/wp-content/plugins/smart-custom-fields
# Exit codes:
# 0 = PATCHED
# 1 = VULNERABLE
# 2 = UNKNOWN / not installed / unable to determine
set -u
TARGET="${1:-}"
if [ -z "$TARGET" ]; then
echo "UNKNOWN - missing argument. Usage: $0 <wordpress-root|plugin-dir>"
exit 2
fi
PLUGIN_DIR=""
if [ -d "$TARGET/wp-content/plugins/smart-custom-fields" ]; then
PLUGIN_DIR="$TARGET/wp-content/plugins/smart-custom-fields"
elif [ -d "$TARGET" ] && [ "$(basename "$TARGET")" = "smart-custom-fields" ]; then
PLUGIN_DIR="$TARGET"
else
echo "UNKNOWN - Smart Custom Fields plugin directory not found under: $TARGET"
exit 2
fi
PLUGIN_FILE=""
for f in "$PLUGIN_DIR"/*.php; do
[ -f "$f" ] || continue
if grep -qi '^\s*Plugin Name:\s*Smart Custom Fields' "$f" 2>/dev/null; then
PLUGIN_FILE="$f"
break
fi
done
version=""
if [ -n "$PLUGIN_FILE" ]; then
version=$(awk -F': *' 'BEGIN{IGNORECASE=1} /^Version:/ {print $2; exit}' "$PLUGIN_FILE" | tr -d '\r')
fi
if [ -z "$version" ] && [ -f "$PLUGIN_DIR/readme.txt" ]; then
version=$(awk -F': *' 'BEGIN{IGNORECASE=1} /^Stable tag:/ {print $2; exit}' "$PLUGIN_DIR/readme.txt" | tr -d '\r')
fi
if [ -z "$version" ]; then
echo "UNKNOWN - could not determine installed version in $PLUGIN_DIR"
exit 2
fi
normalize_ver() {
local v="$1"
local IFS='.'
local parts=($v)
local a=${parts[0]:-0}
local b=${parts[1]:-0}
local c=${parts[2]:-0}
printf '%d%03d%03d\n' "$a" "$b" "$c"
}
installed=$(normalize_ver "$version")
fixed=$(normalize_ver "5.0.1")
if [ "$installed" -lt "$fixed" ]; then
echo "VULNERABLE - Smart Custom Fields version $version (< 5.0.1)"
exit 1
else
echo "PATCHED - Smart Custom Fields version $version (>= 5.0.1)"
exit 0
fi
If you remember one thing.
smart-custom-fields, confirm whether Contributor-style roles exist, and patch any stragglers during normal plugin maintenance. For a LOW finding there is no noisgate mitigation SLA and no noisgate remediation SLA—treat it as backlog hygiene—but if a site allows self-registration, many non-admin authors, or shared editorial workflows, move it to the front of your WordPress queue and update to 5.0.1+ in the next routine change window rather than letting it drift indefinitely.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.