Handing a contributor a spray can in a small-town WordPress gallery nobody guards
CVE-2024-1234 is a stored cross-site scripting flaw in the Exclusive Addons for Elementor WordPress plugin, versions ≤ 2.6.9. The vulnerability lives in the s data attribute across multiple Elementor widgets, where insufficient input sanitization and output escaping allow an authenticated user with Contributor role or above to inject arbitrary JavaScript. That script persists in the page and fires whenever *any* user* — including administrators — views it. The fix landed in version 2.6.9.1, and the current release is 2.8.1. The plugin has roughly 50,000 active installations, making it a niche Elementor add-on rather than a platform-wide attack surface.
The vendor CVSS of 6.4 MEDIUM (using UI:N) overstates the real-world impact. Stored XSS *does* require a victim to load the poisoned page (UI:R), which drops the base score to 5.4. More importantly, the attacker must already hold a WordPress Contributor account — this is not an unauthenticated drive-by. With only ~50K installs, no KEV listing, no known campaigns, and an EPSS of just 1.59%, the vendor severity is generous. A downgrade within the MEDIUM band is warranted.
4 steps from start to impact.
Obtain WordPress Contributor credentials
- WordPress site running Exclusive Addons for Elementor ≤ 2.6.9
- Attacker holds a valid Contributor (or higher) account
- Most enterprise WordPress deployments disable open registration
- Contributor accounts are relatively uncommon in small-team blogs
- MFA on wp-login blocks credential-stuffing paths
Inject XSS payload via Elementor widget
s data attribute. The payload is stored server-side in the post content. The public PoC on Exploit-DB (EDB-52126) demonstrates a trivial <script>alert('XSS')</script> injection.- Contributor can access the Elementor page builder
- The vulnerable widget (e.g., InfoBox, Post Grid, Button) is available
- Contributors can create posts but typically cannot *publish* them — an admin must approve and publish for the payload to reach visitors
- Some WAFs (Wordfence, Sucuri, Cloudflare managed rules) strip
<script>and event-handler patterns from post content
Victim views the poisoned page
- The poisoned post/page must be published or in preview
- A higher-privileged user must visit the page
- Contributors cannot publish directly — the post sits in 'Pending Review' until approved
- Admin previewing a pending post in a sandboxed environment or incognito reduces cookie exposure
- Content Security Policy (CSP) headers with strict
script-srcdirectives block inline script execution
Session hijack or privilege escalation
- Injected JavaScript successfully executes in admin context
- No CSP or HttpOnly cookie flags blocking exfiltration
- WordPress sets
HttpOnlyon auth cookies by default since 4.0, blocking JS-based cookie theft — attacker must use nonce-based API abuse instead - Modern browsers enforce SameSite cookie policies limiting cross-origin exfiltration
wp_kses and esc_attr sanitization to widget data attributes. Since this is a MEDIUM verdict, the noisgate remediation SLA gives you 365 days, but the fix is a one-click plugin update — just do it now.Content-Security-Policy: script-src 'self' (no 'unsafe-inline') on all WordPress responses. This blocks inline <script> execution regardless of stored XSS, neutralizing the payload. Deploy via your reverse proxy or a WordPress security plugin header.Settings → General → Anyone can register is unchecked. This eliminates the PR:L prerequisite entirely.<script> tags and event-handler attributes. This catches the known PoC payload.- IP-based allowlisting on wp-admin — does not help because the attacker is an authenticated Contributor using the legitimate Elementor editor, from a legitimate IP.
- Two-factor authentication on wp-login — useful for preventing credential compromise but does not help if the attacker already has valid Contributor credentials (e.g., a malicious insider or compromised agency account).
- Disabling XML-RPC — irrelevant; this XSS is injected through the Elementor page builder REST API, not XML-RPC.
The supporting signals.
| In-the-wild exploitation | No known campaigns. Not listed in CISA KEV. No threat-intel reports reference active exploitation of this CVE. |
|---|---|
| Proof of concept | Public PoC on Exploit-DB (EDB-52126). Trivial <script> injection via Elementor widget data attribute. Multiple GitHub forks exist but are largely duplicates. |
| EPSS | 0.01593 (1.59% probability of exploitation in 30 days), 72.7th percentile. Low but not negligible. |
| KEV status | Not listed. No CISA KEV entry as of 2026-09-26. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N (vendor: 6.4). More accurate with UI:R → 5.4. Scope change (S:C) is valid since the XSS executes in a different user's browser session. |
| Affected versions | Exclusive Addons for Elementor ≤ 2.6.9 (all prior versions). |
| Fixed versions | 2.6.9.1 (initial fix). Subsequent releases 2.6.9.2–2.6.9.8 fixed XSS in additional widgets (InfoBox, Post Grid, Button, Countdown, Call to Action, Team Member, Card). Current release: 2.8.1. |
| Installed base | ~50,000 active WordPress installations per wordpress.org. Niche Elementor add-on — compare to Essential Addons for Elementor at 2M+. |
| Disclosure date | 2024-03-13. Patch changeset #3042217 published same day. |
| Credit | Researcher not publicly credited in NVD or Wordfence advisory. Reported via Wordfence Bug Bounty Program. |
Sources.
Why this verdict
- Contributor auth required (PR:L): The attacker must already hold a valid WordPress Contributor account. This is not unauthenticated remote access — it presupposes either credential compromise or open registration, narrowing the reachable population significantly.
- User interaction misscored: The vendor vector uses
UI:Nbut stored XSS objectively requires the victim to load the page (UI:R). Correcting this alone drops the base score from 6.4 to 5.4. - Tiny installed base: ~50,000 active installations is minuscule in WordPress-plugin terms. For comparison, Essential Addons for Elementor has 2M+ installs. The exposed population is narrow.
- No active exploitation: Not on KEV, no known campaigns, EPSS at 1.59%. Over two years post-disclosure with a public PoC and still no weaponization in the wild — this is a low-interest target for real adversaries.
- WordPress HttpOnly cookies: Since WordPress 4.0, authentication cookies are
HttpOnlyby default, blocking the simplest XSS-to-session-theft path. The attacker must craft nonce-based API abuse, which raises real-world complexity. - Contributor publish friction: WordPress Contributors cannot publish posts. The poisoned page sits in 'Pending Review' until an editor or admin approves it — adding a human gate that breaks the automated chain.
- Role multiplier: WordPress sites running this niche UI widget plugin overwhelmingly occupy low-value (personal blogs) to typical (business websites) roles. They are not identity infrastructure, network edge devices, hypervisors, or CI/CD systems. Even full admin compromise is host-scoped — limited to a single WordPress instance. No high-value-role floor applies.
Why not higher?
Upgrading to HIGH would require either unauthenticated access, active exploitation, or a blast radius beyond the individual WordPress instance. None apply here. The contributor-auth gate, publish-approval friction, 50K install base, and host-scoped impact all argue against HIGH. The affected component is a cosmetic WordPress widget library, not infrastructure software.
Why not lower?
Stored XSS is still a real privilege-escalation vector in multi-author WordPress environments where contributors are semi-trusted. A public PoC exists and the exploitation complexity is low once authenticated. The scope-change property (S:C) is legitimate — the attacker's injected code runs in a different user's security context. Dropping to LOW would understate the risk in organizations that grant Contributor access to external content authors or agencies.
Crowdsourced verification payload.
Run this script on the WordPress server (or any host with wp-cli configured for the target site) as a user with read access to the WordPress installation directory. Example: bash check_cve_2024_1234.sh /var/www/html/wordpress. No root required.
#!/usr/bin/env bash
# check_cve_2024_1234.sh — Detect CVE-2024-1234 in Exclusive Addons for Elementor
# Usage: bash check_cve_2024_1234.sh /path/to/wordpress
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -euo pipefail
WP_ROOT="${1:-/var/www/html}"
PLUGIN_DIR="$WP_ROOT/wp-content/plugins/exclusive-addons-for-elementor"
PLUGIN_FILE="$PLUGIN_DIR/exclusive-addons-for-elementor.php"
# Check if plugin exists
if [ ! -f "$PLUGIN_FILE" ]; then
echo "UNKNOWN — Exclusive Addons for Elementor not found at $PLUGIN_DIR"
exit 2
fi
# Extract version from plugin header
VERSION=$(grep -i '^[[:space:]]*\*[[:space:]]*Version:' "$PLUGIN_FILE" | head -1 | sed 's/.*Version:[[:space:]]*//' | tr -d '[:space:]')
if [ -z "$VERSION" ]; then
echo "UNKNOWN — Could not determine plugin version from $PLUGIN_FILE"
exit 2
fi
echo "Detected Exclusive Addons for Elementor version: $VERSION"
# Compare versions — vulnerable if <= 2.6.9
# Use sort -V for version comparison
FIXED="2.6.9.1"
if printf '%s\n%s' "$FIXED" "$VERSION" | sort -V | head -1 | grep -qx "$FIXED"; then
echo "PATCHED — Version $VERSION is >= $FIXED (CVE-2024-1234 fixed)"
exit 0
else
echo "VULNERABLE — Version $VERSION is below $FIXED (CVE-2024-1234 applies)"
exit 1
fi