This is a fake note slid under an admin’s office door, not a burglar kicking in the front gate
CVE-2025-22297 is a CSRF flaw in the WordPress plugin AI WP Writer affecting versions through 3.8.4.4, fixed in 3.8.4.5. Per WPScan, the root cause is missing or incorrect nonce validation in the plugin's options() function, which means a logged-in site administrator can be tricked into sending a forged request that changes plugin settings.
The vendor's MEDIUM 4.3 is technically fair in a vacuum, but for enterprise prioritization it still overstates the operational urgency. The exploit needs a live admin session and successful social engineering, the impact described publicly is limited to settings modification rather than code execution or credential theft, there is no KEV listing, and the plugin's public install base is only about 3,000 active sites on WordPress.org.
4 steps from start to impact.
Find a site using the plugin
ai-wp-writer, typically by plugin enumeration or routine WordPress fingerprinting. Public references show the plugin is active and distributed via WordPress.org, but there is no evidence of broad internet-scale exploitation or dedicated scanning for this CVE.- Target runs WordPress with the AI WP Writer plugin installed
- Attacker can identify or guess that the plugin is present
- Plugin-specific fingerprinting is weaker than for top-tier plugins
- The public install base is small relative to mainstream WordPress plugins
Lure an authenticated admin
- A site administrator is currently authenticated to
/wp-admin - The admin clicks a crafted link or loads attacker-controlled content
- Requires social engineering instead of direct remote reachability
- Admin sessions may be short-lived or isolated to separate browsers
- MFA does not help once the authenticated session already exists, but it does reduce casual admin reuse across devices
Abuse missing nonce validation in options()
options() allows unauthorized settings changes under the admin's existing privileges.- The vulnerable plugin version is
<= 3.8.4.4 - The request reaches the plugin settings handler in an authenticated admin context
- This is not an unauthenticated server-side exploit path
- The public description supports settings modification, not arbitrary file write or RCE
wp_options around admin browsing activity.Change plugin behavior, not the whole server
- The site materially depends on AI WP Writer settings
- Changed settings are not immediately noticed and reverted
- Blast radius is constrained to what the plugin settings actually control
- Operational staff may quickly notice content or configuration drift
The supporting signals.
| In-the-wild status | No public evidence of active exploitation found in the sources reviewed; OpenCVE shows KEV: no and CISA's KEV catalog does not list this CVE. |
|---|---|
| Proof-of-concept availability | No public GitHub exploit repo surfaced in primary search results. The exploit path is simple enough to reproduce with a basic forged HTML request, but there is no sign of mature weaponization. |
| EPSS | 0.00125 from the user-provided intel block, which is consistent with a low-likelihood, low-priority exploitation profile for a CSRF admin-click bug. |
| KEV status | Not KEV-listed as of the reviewed CISA catalog, and OpenCVE also marks it KEV no. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N — the key limiter is UI:R. No confidentiality impact, no availability impact, and only low integrity impact are exactly why this does not deserve urgent patch treatment. |
| Affected versions | AI WP Writer through 3.8.4.4 is affected. The CVE record and Wordfence both describe the vulnerable range as <= 3.8.4.4. |
| Fixed version | 3.8.4.5 is the first fixed release per the CVE CNA record and WPScan. Current WordPress.org version is much newer (4.5.8.3 at review time), so routine upgrades also clear this issue. |
| Exposure / scanning | Public scan engines do not reliably fingerprint this plugin from the open internet. The best population proxy here is WordPress.org's 3,000+ active installs and Wordfence's recorded 95,823 downloads, which points to a small-to-moderate niche plugin footprint, not a mass-enterprise exposure event. |
| Disclosure timeline | CVE was published on 2025-01-07 in the Patchstack-assigned CNA record; WPScan lists public publication on 2025-01-06 and Wordfence lists the vulnerability on January 6, 2025. |
| Researcher / reporter | The issue is attributed to Dhabaleshwar Das; the CVE was assigned by Patchstack and tracked by WPScan and Wordfence. |
noisgate verdict.
The decisive downgrading factor is that this bug requires an already authenticated administrator to be socially engineered into triggering it. That turns it from an internet-reachable server flaw into a narrow admin-workflow problem with limited blast radius and no public exploitation signal.
Why this verdict
- Baseline down: vendor scored it 4.3/MEDIUM, but that assumes the integrity impact matters more than the access path friction
- Major friction: exploitation requires a logged-in administrator plus a successful lure/click, which implies post-targeting and user interaction rather than direct remote abuse
- Population is narrow: WordPress.org shows roughly 3,000 active installs, so even among WordPress shops this is not a mass-footprint plugin
- Blast radius is limited: the public description supports plugin settings changes, not code execution, arbitrary file write, or full site takeover
- No threat signal: not in KEV, no public active exploitation evidence found, and the provided EPSS is very low
Why not higher?
There is no unauthenticated server-side path here. An attacker does not get to hit the target cold from the internet; they need the admin to be logged in and to cooperate by action, and even then the described impact is limited to settings manipulation.
Why not lower?
This is still a real integrity flaw, not paperwork. On sites that actively use the plugin, forged settings changes can alter publishing behavior or create spam/SEO cleanup work, and the attack primitive is simple once the attacker has an engaged admin target.
What to do — in priority order.
- Restrict admin access paths — Put
/wp-adminbehind VPN, allowlists, or SSO with conditional access where possible. That does not fix CSRF by itself, but it reduces the pool of admins who can be actively targeted; for a LOW verdict, do this during normal hardening work because there is no fixed noisgate mitigation SLA. - Shorten and isolate admin sessions — Use separate admin-only browsers or profiles and reduce idle session lifetime so fewer admins are casually logged in while reading mail or browsing. This directly attacks the main prerequisite for CSRF and should be folded into routine admin hygiene with backlog priority, not emergency change.
- Monitor plugin option changes — Enable WordPress audit logging and alert on unexpected modifications to AI WP Writer settings or related
wp_optionsentries. For a LOW issue, deploy this in the next scheduled monitoring improvement cycle if you cannot patch immediately. - Enable controlled plugin updates — If you operate WordPress at scale, keep AI WP Writer on an approved plugin update channel so vulnerable versions do not linger. For this severity, schedule it as backlog hygiene rather than expedited emergency remediation.
- A generic perimeter WAF alone does not solve this, because the forged request rides a legitimate authenticated admin session and may look normal to the server.
- Host EDR is usually not the answer here; the exploit is a browser-driven web request, not malware dropping on the server.
- MFA by itself does not block CSRF once the administrator already has an active session cookie.
Crowdsourced verification payload.
Run this on the target WordPress host with read access to the plugin directory. Invoke it as bash check-ai-wp-writer-cve-2025-22297.sh /var/www/html or point it directly at the plugin directory root; no root privileges are required unless your web files are permission-restricted.
#!/usr/bin/env bash
# check-ai-wp-writer-cve-2025-22297.sh
# Detect AI WP Writer versions affected by CVE-2025-22297.
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN, 3=usage error
set -u
FIXED_VERSION="3.8.4.5"
TARGET_PATH="${1:-}"
PLUGIN_SLUG="ai-wp-writer"
usage() {
echo "Usage: $0 <wordpress_root_or_plugin_dir>"
exit 3
}
if [[ -z "$TARGET_PATH" ]]; then
usage
fi
if [[ ! -e "$TARGET_PATH" ]]; then
echo "UNKNOWN - path does not exist: $TARGET_PATH"
exit 2
fi
# Resolve plugin dir whether caller passed WP root or plugin dir
PLUGIN_DIR=""
if [[ -d "$TARGET_PATH/wp-content/plugins/$PLUGIN_SLUG" ]]; then
PLUGIN_DIR="$TARGET_PATH/wp-content/plugins/$PLUGIN_SLUG"
elif [[ -d "$TARGET_PATH/$PLUGIN_SLUG" ]]; then
PLUGIN_DIR="$TARGET_PATH/$PLUGIN_SLUG"
elif [[ -d "$TARGET_PATH" && "$(basename "$TARGET_PATH")" == "$PLUGIN_SLUG" ]]; then
PLUGIN_DIR="$TARGET_PATH"
else
echo "UNKNOWN - could not locate plugin directory for $PLUGIN_SLUG under: $TARGET_PATH"
exit 2
fi
verlte() {
# returns success if $1 <= $2
[[ "$1" == "$2" ]] && return 0
local first
first=$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)
[[ "$first" == "$1" ]]
}
extract_version_from_file() {
local file="$1"
local ver
ver=$(grep -Eim1 '^[[:space:]]*Version:[[:space:]]*' "$file" 2>/dev/null | sed -E 's/^[[:space:]]*Version:[[:space:]]*//I' | tr -d '\r')
if [[ -n "$ver" ]]; then
echo "$ver"
return 0
fi
return 1
}
VERSION=""
SOURCE_FILE=""
# Prefer readme.txt if present
if [[ -f "$PLUGIN_DIR/readme.txt" ]]; then
VERSION=$(extract_version_from_file "$PLUGIN_DIR/readme.txt" || true)
if [[ -n "$VERSION" ]]; then
SOURCE_FILE="$PLUGIN_DIR/readme.txt"
fi
fi
# Fall back to plugin PHP headers
if [[ -z "$VERSION" ]]; then
while IFS= read -r -d '' phpfile; do
VERSION=$(extract_version_from_file "$phpfile" || true)
if [[ -n "$VERSION" ]]; then
SOURCE_FILE="$phpfile"
break
fi
done < <(find "$PLUGIN_DIR" -maxdepth 2 -type f -name '*.php' -print0 2>/dev/null)
fi
if [[ -z "$VERSION" ]]; then
echo "UNKNOWN - could not extract plugin version from $PLUGIN_DIR"
exit 2
fi
if verlte "$VERSION" "$FIXED_VERSION" && [[ "$VERSION" != "$FIXED_VERSION" ]]; then
echo "VULNERABLE - AI WP Writer version $VERSION detected in $SOURCE_FILE (fixed in $FIXED_VERSION)"
exit 1
elif [[ "$VERSION" == "$FIXED_VERSION" ]]; then
echo "PATCHED - AI WP Writer version $VERSION detected in $SOURCE_FILE"
exit 0
else
echo "PATCHED - AI WP Writer version $VERSION detected in $SOURCE_FILE"
exit 0
fi
If you remember one thing.
ai-wp-writer and flag any site at 3.8.4.4 or earlier. Because this lands LOW after friction audit, there is noisgate mitigation SLA: no SLA (treat as backlog hygiene) and noisgate remediation SLA: backlog hygiene rather than an expedited window; in practice, roll the plugin to 3.8.4.5 or later in your next normal WordPress plugin maintenance cycle, and if an affected site has exposed or high-churn admins, tighten admin access and session hygiene while you wait.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.