This is a booby-trapped note slipped into a page draft, not a skeleton key to the building
CVE-2025-22316 is a stored XSS in the WordPress plugin WPBITS Addons For Elementor Page Builder affecting versions through 1.5.1; fixes landed in 1.6. The bug exists because some widget input is not sanitized on the way in and not safely escaped on the way out, letting an attacker with at least Author-level access plant JavaScript into content that later runs in another user's browser.
The vendor's MEDIUM 5.9 is already directionally conservative, but for enterprise patch triage this deserves a downgrade to LOW. The decisive friction is that exploitation is post-authentication and needs a fairly specific setup: a reachable WordPress site running a niche plugin, a valid author-capable account, vulnerable widget usage, and a victim with higher privilege who actually loads the poisoned page.
4 steps from start to impact.
Get Author+ access
- Target runs WordPress with
wpbits-addons-for-elementorinstalled - Plugin version is 1.5.1 or older
- Attacker has valid Author+ credentials
- This is not unauthenticated internet exploitation
- Many enterprise WordPress sites do not grant Author broadly
- MFA, SSO, and access reviews often stop this before the CVE matters
Store the payload in vulnerable widget content
- Attacker can create or edit content using affected WPBITS widgets
- The specific field accepts attacker-controlled content
- Stored payload survives save and render paths
- Not every site uses the affected widget paths
- Some WAFs or CSP deployments may catch noisy payloads
- Editorial review workflows may notice suspicious content before publication
<script> or event-handler payloads.Wait for a higher-value user to render the page
/wp-admin. The payload can then steal nonces, abuse the admin's session, or trigger admin-only actions.- A victim with a more privileged session visits the poisoned page or preview
- Browser executes the stored JavaScript
- Victim has cookies/nonces useful to the attacker
- The UI:R requirement is real and meaningfully reduces exploit certainty
- Admins may not ever view the malicious page while logged in
- HttpOnly cookies, nonce lifetimes, CSP, and browser protections can limit follow-on abuse
Pivot to site-level impact
- Victim is an administrator or equivalent
- Payload successfully captures actionable tokens/nonces or drives state-changing requests
- Site permissions allow high-impact admin actions
- Impact is usually site-scoped, not enterprise-wide
- Shared admin panels and reused credentials are what turn this from nuisance to incident
- Well-isolated hosting and separate admin accounts contain fallout
The supporting signals.
| In-the-wild status | No authoritative evidence of active exploitation found in reviewed sources, and CISA KEV does not list CVE-2025-22316. |
|---|---|
| Proof-of-concept availability | No reliable public PoC repo surfaced in reviewed primary sources. That said, weaponization is low-skill once an attacker has Author+ access; a browser or Burp Suite is enough. |
| EPSS | 0.00091 (~0.091% next-30-day exploit probability), which is consistent with a low-priority, niche, post-auth WordPress plugin issue. |
| KEV status | Not KEV-listed. No CISA due date applies because the CVE is absent from the catalog. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:L — network reachable in theory, but it requires high privileges and user interaction, which are the two biggest downward pressure factors in real deployments. |
| Affected versions | Authoritative advisories align on WPBITS Addons For Elementor Page Builder <= 1.5.1 as vulnerable. |
| Fixed version | Fixed in 1.6. The WordPress.org changelog for 1.6 mentions minor security improvements, matching the advisory timing. |
| Exposure population | WordPress.org lists only 2,000+ active installations for the plugin. That is a small exposure population compared with mainstream WordPress plugins, and there is no reliable Shodan/Censys fingerprint for direct internet enumeration of this specific vulnerable addon. |
| Disclosure timeline | CVE published by NVD on 2025-01-07; WPScan shows public publication on 2025-01-06. |
| Researcher / detection coverage | WPScan credits researcher Michael. Detection/advisory coverage exists in WPScan, Wordfence, and NVD, but most enterprise network scanners will not verify exploitability without authenticated app context. |
noisgate verdict.
The single biggest reason this lands in LOW is the Author+ authentication requirement: this is a post-initial-access content abuse bug, not an edge compromise. Even if exploited, the likely blast radius is one WordPress site and only after a second user with more privilege actually renders the poisoned content.
Why this verdict
- Downward pressure: requires authenticated Author+ access — that implies the attacker already has a foothold, insider status, or stolen CMS credentials before the CVE matters.
- Downward pressure: user interaction is required — a victim still has to load the poisoned content, and that extra hop breaks a lot of opportunistic exploitation.
- Downward pressure: narrow exposure population — the plugin has only 2,000+ active installs on WordPress.org, so the reachable target pool is small compared with mass-exploited plugin bugs.
- Upward pressure: stored XSS can become privilege abuse — if an admin loads the page while authenticated, the attacker may pivot to site-admin actions.
- Downward pressure: no exploitation signal — no KEV listing, no solid in-the-wild reporting in reviewed sources, and a very low EPSS 0.00091.
Why not higher?
This is not an unauthenticated edge bug, not an RCE, and not broadly wormable. Requiring Author+ access plus a second privileged user to render the payload makes the exploitation chain too conditional for MEDIUM/HIGH patch priority in a large enterprise queue.
Why not lower?
It is still a persistent stored XSS, not a self-XSS or theoretical parser quirk. On multi-author WordPress sites, compromised publisher accounts are common enough that this can become a real site-takeover path if administrators routinely preview or moderate content.
What to do — in priority order.
- Restrict Author role issuance — Treat Author and above as privileged web-content execution roles, not routine editorial access. Review who can create/edit Elementor content and remove stale accounts; for a LOW verdict there is no SLA, so handle this as backlog hygiene during the next access-review cycle.
- Enforce MFA on WordPress and SSO — This bug only matters after credentialed access, so MFA directly attacks the most important prerequisite. For a LOW verdict there is no SLA, but this belongs in your standard identity-hardening program rather than emergency patching.
- Add or tighten CSP where feasible — A restrictive Content Security Policy can reduce the reliability of inline or external script execution from stored XSS payloads, especially on front-end page views. For LOW, there is no SLA; roll it out carefully because WordPress/Elementor themes often need tuning.
- Audit Elementor content for script-bearing fields — Search posts, pages, and relevant post meta for suspicious tags, event handlers, or encoded payloads in WPBITS-controlled content. For LOW, there is no SLA; do this as part of routine WordPress hygiene if the plugin is present.
- Monitor admin-side changes — Alert on new admin users, plugin installs, theme edits, and unusual settings changes following content publication or page preview events. For LOW, there is no SLA; place these detections into your normal CMS monitoring backlog.
- A perimeter vulnerability scan alone does not validate this issue, because the exploit path depends on authenticated CMS behavior and victim page rendering.
- Patching only the web server or PHP runtime does not address the unsafe input/output handling in the plugin.
- Relying on user training alone does not solve it; the dangerous action is often a normal admin preview or moderation workflow, not an obviously malicious click.
Crowdsourced verification payload.
Run this on the target WordPress host or inside the container/VM that serves the site. Invoke it as bash check-wpbits-cve-2025-22316.sh /var/www/html or point it directly at the plugin dir; it needs read access to the WordPress files, not root unless your web content is permission-restricted.
#!/usr/bin/env bash
# check-wpbits-cve-2025-22316.sh
# Determine whether WPBITS Addons For Elementor Page Builder is vulnerable to CVE-2025-22316
# Affected: <= 1.5.1
# Patched: >= 1.6
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
TARGET="${1:-.}"
PLUGIN_SLUG="wpbits-addons-for-elementor"
PLUGIN_DIR=""
VERSION=""
find_plugin_dir() {
local base="$1"
if [ -d "$base/wp-content/plugins/$PLUGIN_SLUG" ]; then
echo "$base/wp-content/plugins/$PLUGIN_SLUG"
return 0
fi
if [ -d "$base/$PLUGIN_SLUG" ]; then
echo "$base/$PLUGIN_SLUG"
return 0
fi
return 1
}
extract_version_from_file() {
local file="$1"
if [ -f "$file" ]; then
awk -F': *' 'BEGIN{IGNORECASE=1} /^Version:/ {print $2; exit}' "$file" | tr -d '\r'
fi
}
version_leq() {
# returns 0 if $1 <= $2
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]
}
version_geq() {
# returns 0 if $1 >= $2
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n1)" = "$1" ]
}
PLUGIN_DIR="$(find_plugin_dir "$TARGET")" || {
echo "UNKNOWN: plugin directory '$PLUGIN_SLUG' not found under '$TARGET'"
exit 2
}
# Try common plugin header files first
for candidate in \
"$PLUGIN_DIR/wpbits-addons-for-elementor.php" \
"$PLUGIN_DIR/plugin.php" \
"$PLUGIN_DIR/index.php" \
"$PLUGIN_DIR/readme.txt"
do
VERSION="$(extract_version_from_file "$candidate")"
if [ -n "$VERSION" ]; then
break
fi
done
# Fallback: grep first Version header anywhere near plugin root
if [ -z "$VERSION" ]; then
VERSION="$(grep -RIm1 '^Version:' "$PLUGIN_DIR" 2>/dev/null | head -n1 | sed 's/^[^:]*:[[:space:]]*//')"
fi
if [ -z "$VERSION" ]; then
echo "UNKNOWN: unable to determine installed plugin version in '$PLUGIN_DIR'"
exit 2
fi
# Normalize version string
VERSION="$(echo "$VERSION" | awk '{print $1}')"
if version_leq "$VERSION" "1.5.1"; then
echo "VULNERABLE: $PLUGIN_SLUG version $VERSION installed at $PLUGIN_DIR"
exit 1
fi
if version_geq "$VERSION" "1.6"; then
echo "PATCHED: $PLUGIN_SLUG version $VERSION installed at $PLUGIN_DIR"
exit 0
fi
# Defensive fallback for unexpected version formats between known ranges
if version_geq "$VERSION" "1.5.2" && version_leq "$VERSION" "1.5.999"; then
echo "PATCHED: $PLUGIN_SLUG version $VERSION installed at $PLUGIN_DIR (not in affected <=1.5.1 range)"
exit 0
fi
echo "UNKNOWN: parsed version '$VERSION' but could not classify confidently"
exit 2
If you remember one thing.
wpbits-addons-for-elementor and identify any installs at 1.5.1 or older, but do not let this jump ahead of unauthenticated edge bugs or KEV-listed items. Because this is LOW, there is no noisgate mitigation SLA and noisgate remediation SLA is backlog hygiene; fold access-control cleanup and monitoring into normal operations, and patch the plugin during the next routine WordPress maintenance cycle rather than launching an emergency change window.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.