A drive-by 'Sold' sticker vandalism trick that only works if the attacker already has a login and a car listing of their own
CVE-2026-12435 is a missing-authorization / nonce-scope flaw (CWE-862) in the *Motors – Car Dealership & Classified Listings* WordPress plugin, affecting all versions up to and including 1.4.111. The plugin exposes a stm_mark_as_sold_car AJAX action that toggles the 'Sold' badge and clears the special_car featured-post meta on a listing. The nonce is generated per-user but not scoped to a specific listing ID, so an authenticated *Subscriber* who owns any listing can harvest a valid nonce from their own add-listing flow and then replay it against any other user's listing post ID, flipping the Sold flag and stripping the 'featured' status on victim ads.
The vendor severity of MEDIUM (4.3) is fair — arguably even slightly generous. The CVSS vector AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N correctly reflects that this is authenticated (PR:L), touches only integrity, and doesn't leak data or crash the site. This is *not* the same class of Motors bug that made headlines earlier this year (CVE-2026-1934 was an unauth admin-takeover chain, CVSS 9.8). Real-world impact here caps at classifieds vandalism on sites that expose Subscriber self-registration — closer to LOW in practitioner terms.
4 steps from start to impact.
Obtain a Subscriber account on the target site
- Target site allows self-registration (WordPress Anyone can register or plugin equivalent)
- Attacker has a working email address
- Sites that gate account creation behind manual approval or email whitelisting block this step outright
- reCAPTCHA / hCaptcha on registration slows automated abuse
wp_users; Wordfence and WPScan flag bulk sign-ups. No CVE-specific IDS signature exists.Create a throwaway listing to mint a nonce
_wpnonce for the stm_mark_as_sold_car AJAX action, tied to the attacker's user but not to the attacker's listing ID.- Subscriber can post at least one listing
- Front-end management UI is enabled (default)
- Sites requiring paid subscription or admin approval before listing publication break this step
Replay the nonce against a victim post ID
/wp-admin/admin-ajax.php with action=stm_mark_as_sold_car, the harvested nonce, and any target listing's post_id. The plugin validates the nonce belongs to *a* user but fails to check ownership of the referenced post. Tooling: curl, Burp Repeater, or a 10-line Python script.- Valid session cookie for the attacker's Subscriber account
- Knowledge of a target post ID (trivially enumerable from public listing URLs)
- None once the first two steps succeed — this is the actual bug
admin-ajax.php traffic per session; WAF rules with per-user rate limits on stm_mark_as_sold_car catch bulk abuse.Victim listing shows 'Sold' and loses featured status
special_car post-meta is stripped, dropping it from featured carousels. Impact is reversible by the site owner via wp-admin but requires manual intervention per listing.- Successful replay in step 3
- No code execution, no privilege gain, no data leakage — impact is purely cosmetic/business-integrity
The supporting signals.
| In-the-wild exploitation | None observed as of 2026-07-01. No GreyNoise tag, no Wordfence live-attack telemetry entry. |
|---|---|
| Public PoC | No standalone PoC repo published yet. The bug pattern (nonce replay across post IDs) is trivial to reproduce from the advisory text — expect a Patchstack/Wordfence writeup within days. |
| EPSS | Not yet scored (disclosed 2026-07-01). Comparable Subscriber-nonce bugs in WordPress plugins historically sit at <1% percentile. |
| KEV status | Not listed. CISA KEV requires evidence of active exploitation; this bug's impact ceiling is too low to attract KEV attention. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N — network-reachable, low complexity, low privileges required (Subscriber), no user interaction, integrity-only impact. Score 4.3 is accurate. |
| Affected versions | All versions ≤ 1.4.111 of the *motors-car-dealership-classified-listings* plugin. |
| Fixed version | 1.4.112 (per vendor advisory / Patchstack). Distro backports N/A — WordPress plugins ship direct from vendor. |
| Exposure population | The Motors ecosystem (theme + plugin) has ~15k–20k active installs per WordPress.org. Public Subscriber registration is common on classifieds sites, so most installs are theoretically reachable — but blast radius per site is minimal. |
| CWE | CWE-862 Missing Authorization. Root cause is a nonce that authenticates the user but not the target object. |
| Reporter / disclosure | Disclosed via Wordfence Intelligence / Patchstack pipeline on 2026-07-01. Researcher credit typically appears in the vendor changelog. |
noisgate verdict.
Impact is capped at integrity-only vandalism of individual classified ads with no path to privilege escalation, code execution, or data disclosure. The single decisive factor is blast radius limited to per-listing cosmetic state, not the ~20k install base.
Why this verdict
- Authenticated-only. PR:L means the attacker must hold a valid Subscriber account. Sites with closed registration or paid-listing gates block the attack at step 1.
- Impact is integrity-only, non-persistent-elevation. C:N/A:N — no data disclosure, no availability loss, no code execution. Victim owners can revert the flag from wp-admin.
- Role multiplier: the affected component is a *classifieds plugin on marketing/dealer sites* — none of the noisgate high-value-role categories apply (not identity, not PKI, not hypervisor, not backup, not CI/CD, not network edge). Worst plausible high-value-role outcome is a competitor sabotaging a rival dealership's featured listings — commercial nuisance, not fleet or supply-chain compromise. Role floor does not push above LOW.
- No exploitation signal. Not on KEV, no GreyNoise tags, no observed campaigns. EPSS will land in the low single digits.
- Downgrade justification vs. vendor 4.3: vendor score already reflects the low impact; noisgate rounds to LOW (3.5) because 'mark-as-sold griefing' does not rise to the operational urgency of a MEDIUM in a 10k-host environment.
Why not higher?
There is no privilege escalation, no RCE, no data leak, and no cross-tenant impact. The nonce scope bug is bounded to a single boolean post-meta field on a single post per request. Even at scale, an attacker gains no foothold — just annoyed dealership customers.
Why not lower?
Not IGNORE because it still enables trivial business-integrity attacks on paid classifieds sites where a 'Sold' badge directly harms revenue for the victim seller. There is a real business case for patching, just not an operational-security emergency.
What to do — in priority order.
- Upgrade Motors plugin to 1.4.112 or later — The vendor fix scopes the nonce to the target post ID. This is the clean fix. Given LOW verdict, deploy within the noisgate remediation window (≤ 365 days) — but for classifieds sites where 'Sold' badge integrity is revenue-linked, treat as a normal monthly plugin-update cadence item.
- Disable open Subscriber registration on sites that don't need it — Uncheck Settings → General → Anyone can register if your business model doesn't require self-serve seller signups. This eliminates step 1 of the chain entirely. No SLA — hygiene setting.
- Add a WAF rule rate-limiting
admin-ajax.php?action=stm_mark_as_sold_carper session — Cap to e.g. 5 requests/hour/user. Wordfence, Sucuri, Cloudflare custom rules all support this. Contains bulk-vandalism scenarios pending plugin upgrade. No mitigation SLA for LOW — apply opportunistically. - Enable audit logging of post-meta changes on
special_carand Sold status — WP Activity Log or Simple History captures who toggled what. Gives dealer support staff a fast rollback path if abuse is reported.
- MFA on Subscriber accounts — the attacker owns the account they're using; MFA doesn't stop a legitimate login from abusing the AJAX endpoint.
- Generic WordPress hardening plugins (iThemes, Solid Security) with default rulesets — they do not know about this specific
stm_mark_as_sold_caraction and won't intercept it unless you add a custom rule. - Blocking XML-RPC / disabling REST API for unauth users — the endpoint used is
admin-ajax.phpfor *authenticated* users; those controls miss it.
Crowdsourced verification payload.
Run this on the WordPress host (or any admin workstation with SSH to it) as a user who can read the plugin directory. Invoke with the plugin path, e.g. ./check-cve-2026-12435.sh /var/www/html/wp-content/plugins/motors-car-dealership-classified-listings. No root required if the wp-content tree is world-readable.
#!/usr/bin/env bash
# noisgate check for CVE-2026-12435 — Motors plugin nonce-replay authz bypass
# Usage: ./check-cve-2026-12435.sh <plugin-dir>
# Exits: 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN
set -u
PLUGIN_DIR="${1:-}"
FIXED_VERSION="1.4.112"
if [[ -z "$PLUGIN_DIR" || ! -d "$PLUGIN_DIR" ]]; then
echo "UNKNOWN: plugin directory not provided or missing" >&2
exit 2
fi
# Locate the main plugin file (has 'Version:' header)
MAIN_FILE=$(grep -rlE '^[[:space:]]*\*?[[:space:]]*Version:[[:space:]]*[0-9]' "$PLUGIN_DIR" --include='*.php' | head -n1)
if [[ -z "$MAIN_FILE" ]]; then
echo "UNKNOWN: could not locate plugin header file" >&2
exit 2
fi
INSTALLED=$(grep -Ei '^[[:space:]]*\*?[[:space:]]*Version:' "$MAIN_FILE" | head -n1 | sed -E 's/.*Version:[[:space:]]*([0-9][0-9.]*).*/\1/')
if [[ -z "$INSTALLED" ]]; then
echo "UNKNOWN: could not parse installed version from $MAIN_FILE" >&2
exit 2
fi
# semver-ish compare: is $INSTALLED >= $FIXED_VERSION ?
lowest=$(printf '%s\n%s\n' "$INSTALLED" "$FIXED_VERSION" | sort -V | head -n1)
if [[ "$lowest" == "$FIXED_VERSION" ]]; then
echo "PATCHED: motors plugin $INSTALLED >= $FIXED_VERSION"
exit 0
fi
# Secondary confirmation — look for the vulnerable handler without a post-scoped check
if grep -RIn --include='*.php' -E "stm_mark_as_sold_car" "$PLUGIN_DIR" >/dev/null 2>&1; then
# crude heuristic: is the nonce checked with a post-id-scoped action string?
if ! grep -RIn --include='*.php' -E "wp_verify_nonce\([^)]*(post_id|listing_id|\\\$post)" "$PLUGIN_DIR" >/dev/null 2>&1; then
echo "VULNERABLE: motors plugin $INSTALLED < $FIXED_VERSION, nonce appears not scoped to post id"
exit 1
fi
fi
echo "VULNERABLE: motors plugin $INSTALLED < $FIXED_VERSION"
exit 1
If you remember one thing.
Sources
- Patchstack — Motors ≤ 1.4.9 Missing Authorization advisory (related)
- Wordfence Intelligence — Motors vulnerability entry
- WPScan — Motors plugin vulnerability history
- WP-Firewall — Motors broken access control writeup (CVE-2026-1934)
- Infosecurity Magazine — Motors WordPress flaw takeover coverage
- SentinelOne vulnerability DB — CVE-2026-1934 background
- CWE-862 Missing Authorization
- CISA KEV catalog (for absence-of-listing confirmation)
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.