This is a side door behind an already locked lobby, not a smashed front window
CVE-2025-22305 is a local file inclusion flaw in the WordPress hero-banner-ultimate plugin from Essential Plugin / WP OnlineSupport. The CVE record says affected versions run through 1.4.2, while Patchstack, Wordfence, WPScan, and Rapid7 all extend exposure through 1.4.4 and point to 1.4.5 as the fix; that version-range mismatch is the main intel wrinkle here. In practical terms, an authenticated user with at least Author-level access can steer the plugin into including local files, which can expose sensitive application files and, in some server/file-upload configurations, turn into code execution.
The vendor's 6.5 MEDIUM score is technically defensible in a lab, but too generous for enterprise patch triage. The decisive reality check is attacker position: this is not unauthenticated internet RCE, it is a post-login, role-gated flaw in a small-footprint WordPress plugin with no KEV listing, tiny EPSS, and no credible in-the-wild exploitation evidence. That combination pushes this down to LOW for most defenders managing broad estate risk.
4 steps from start to impact.
Get valid WordPress Author+ access
hero-banner-ultimate. Typical tooling here is WPScan for enumeration and a standard phishing / credential-stuffing playbook for access, not a one-packet exploit. This prerequisite makes the flaw post-initial-access by default.- Internet-reachable or otherwise reachable WordPress site
- Valid WordPress credentials
- Role is Author or higher
- MFA blocks a lot of commodity account takeover
- Many enterprises do not grant Author accounts broadly
- This already assumes another control failed earlier in the kill chain
Confirm the vulnerable plugin and version
Burp Suite or simple browser inspection. Public intel disagrees on the exact ceiling version, but multiple downstream sources align on vulnerable builds through 1.4.4 with 1.4.5 fixed. If the plugin is absent or already updated, the chain dies here.- Plugin
hero-banner-ultimateinstalled - Version within vulnerable range
- Plugin footprint appears small; WPScan last showed about 1,000 active installs
- A lot of enterprise web estates do not run this plugin at all
- Version ambiguity complicates broad scanner signatures
Abuse file-include parameter for local file read
Burp Suite, curl, or a custom HTTP request, the attacker feeds a crafted path into the vulnerable include/require flow. The most realistic first-stage outcome is reading local files such as wp-config.php, plugin PHP, or other webroot content. That can leak database credentials, salts, filesystem paths, and other secrets.- Reachable vulnerable endpoint or action
- Input reaches include/require without safe validation
- Some paths may fail due to filesystem layout differences
- Hardened PHP settings and file permissions reduce reachable content
- LFI does not automatically equal code execution
Pivot from file read to broader compromise
wp-config.php or equivalent secrets are exposed, the attacker can pivot with database access, password-salt abuse, or lateral movement inside that web app stack. In more permissive deployments, uploaded files or poisoned files may be included to execute PHP, but that is configuration-dependent rather than guaranteed. The likely blast radius is the single site or tenant, not the whole enterprise estate.- Useful secrets available locally
- Or a writable/include-able file path exists for execution
- Database may be isolated and not remotely reachable
- Managed WordPress platforms often constrain filesystem and PHP abuse paths
- Tenant-level compromise does not inherently become domain-wide compromise
wp-config.php access anomalies, unusual DB connections from web tiers, suspicious admin actions, and post-auth webshell/SEO-spam behavior.- A perimeter-only WAF is not enough; the exploit lives behind authenticated WordPress workflows, where many WAF deployments have weaker visibility and looser blocking.
- Network segmentation alone does not solve the core issue; the vulnerable code executes inside the web app, and the first meaningful gate is account/role control.
- Relying on CVSS alone does not help prioritize this correctly; the lab impact sounds worse than the real-world reachable population.
The supporting signals.
| In-the-wild status | No solid public evidence of active exploitation found, and not listed in CISA KEV. CISA ADP enrichment on the CVE record also marks exploitation as none. |
|---|---|
| Proof-of-concept availability | No reputable public PoC repo surfaced in source review. Public writeups are advisory-style entries from Patchstack, Wordfence, WPScan, and Rapid7 rather than weaponized exploit code. |
| EPSS | 0.00242 per user-supplied intel from FIRST EPSS upstream — extremely low predicted exploitation probability. |
| KEV status | Not KEV-listed as of this assessment; that materially lowers urgency versus internet-scale WordPress bugs that land in active exploitation catalogs. |
| CVSS vector meaning | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N means remote reachability but requires prior low privileges. The score is driven by confidentiality impact, not broad unauthenticated takeover. |
| Affected versions | There is a source mismatch: the CVE/CNA record says through 1.4.2, while Patchstack, Wordfence, WPScan, and Rapid7 all indicate through 1.4.4. |
| Fixed version | Patchstack and WPScan both identify 1.4.5 as the security fix; WordPress.org currently shows plugin version 1.4.6 and the plugin page says the plugin was permanently closed on 2026-04-07. |
| Exposure / internet census | WPScan last exposed ~1,000 active installs. There is no clean Shodan/Censys-style network fingerprint for a WordPress plugin like this, so internet-wide counts are weak and plugin telemetry is the better proxy. |
| Disclosure and attribution | Published on 2025-01-07 in the CVE record; credited researcher is João Pedro S Alcântara (Kinorth) via Patchstack Alliance / Bug Bounty reporting. |
| Operational read-through | This is a post-auth niche-plugin LFI. For enterprise prioritization, the narrow exposure population and Author+ prerequisite outweigh the scary-sounding include/require weakness. |
Sources.
Why this verdict
- Requires prior auth:
PR:Lhere is not a footnote; it means the attacker already has a WordPress foothold and at least Author rights. - Exposure population is small: WPScan showed roughly
1,000active installs, which is tiny compared with mass-targeted WordPress plugins. - No active-exploitation pressure: no KEV entry, no credible public campaign reporting, and the supplied EPSS is extremely low at
0.00242.
Why not higher?
If this were unauthenticated or broadly deployed, the include/require bug class would justify a much louder response. But the chain compounds downward: niche plugin, prior login required, role-gated access, and no strong evidence of widespread weaponization.
Why not lower?
It still should not be ignored because local file inclusion against a live CMS can expose wp-config.php, database credentials, auth salts, and application secrets. In some deployments the same primitive can be pushed further toward code execution, so there is real per-site impact once the attacker is inside.
Crowdsourced verification payload.
Run this on the target WordPress host or on a configuration-management worker with filesystem access to the site. Invoke it as bash check_hero_banner_ultimate_cve_2025_22305.sh /var/www/html and use an account that can read the plugin directory; root is not required unless your webroot permissions are locked down.
#!/usr/bin/env bash
# check_hero_banner_ultimate_cve_2025_22305.sh
# Detects whether the Hero Banner Ultimate WordPress plugin is in a version range
# commonly reported as vulnerable to CVE-2025-22305.
#
# Usage:
# bash check_hero_banner_ultimate_cve_2025_22305.sh /path/to/wordpress
#
# Exit codes:
# 0 = PATCHED
# 1 = VULNERABLE
# 2 = UNKNOWN
set -u
WP_ROOT="${1:-}"
PLUGIN_DIR=""
VERSION=""
if [[ -z "$WP_ROOT" ]]; then
echo "UNKNOWN - missing WordPress root path argument"
exit 2
fi
PLUGIN_DIR="$WP_ROOT/wp-content/plugins/hero-banner-ultimate"
MAIN_FILE="$PLUGIN_DIR/hero-banner-ultimate.php"
README_FILE="$PLUGIN_DIR/readme.txt"
if [[ ! -d "$PLUGIN_DIR" ]]; then
echo "UNKNOWN - plugin directory not found: $PLUGIN_DIR"
exit 2
fi
extract_version() {
local f="$1"
if [[ -f "$f" ]]; then
awk -F': *' '
BEGIN{IGNORECASE=1}
/^Version:/ {print $2; exit}
/^Stable tag:/ {print $2; exit}
' "$f" | tr -d '\r'
fi
}
VERSION="$(extract_version "$MAIN_FILE")"
if [[ -z "$VERSION" ]]; then
VERSION="$(extract_version "$README_FILE")"
fi
if [[ -z "$VERSION" ]]; then
echo "UNKNOWN - could not determine plugin version from $MAIN_FILE or $README_FILE"
exit 2
fi
# Source intelligence conflict exists between <=1.4.2 and <=1.4.4.
# This checker uses the broader consensus from Patchstack/Wordfence/WPScan/Rapid7:
# vulnerable through 1.4.4, fixed in 1.4.5.
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" ]]
}
vergte() {
# returns success if $1 >= $2
[[ "$1" == "$2" ]] && return 0
local first
first=$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)
[[ "$first" == "$2" ]]
}
if verlte "$VERSION" "1.4.4"; then
echo "VULNERABLE - Hero Banner Ultimate version $VERSION detected (treat <=1.4.4 as vulnerable)"
exit 1
fi
if vergte "$VERSION" "1.4.5"; then
echo "PATCHED - Hero Banner Ultimate version $VERSION detected"
exit 0
fi
echo "UNKNOWN - version $VERSION did not map cleanly to expected ranges"
exit 2