A back-door pass into the storeroom that only reads the packing slips, not the products
The Avada (Fusion) Builder plugin's fusion_get_post_custom_field() helper accepts a post_custom_field parameter from the Dynamic Data feature and returns the requested meta value without checking whether the key begins with an underscore. In WordPress, an underscore prefix is the canonical marker for *protected* post meta — used by ecommerce plugins, license managers, and custom workflows to store internal state like SKUs, payment tokens, hidden order data, or plugin scratch fields. All versions ≤ 3.15.1 are affected; the vendor shipped the fix in 3.15.2, which validates the requested key against is_protected_meta() before returning the value.
The vendor MEDIUM (4.3) label is honest. The CVSS vector AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N correctly captures a network-reachable, authenticated, confidentiality-only leak with no integrity or availability impact. If anything, in a hardened WordPress install where open Subscriber registration is disabled, the real-world reachable population is smaller than the vector implies — pushing this into LOW territory for most enterprise footprints. It is not a system-compromise bug; it is a reconnaissance primitive.
4 steps from start to impact.
Obtain a Subscriber-level account on the target site
Anyone can register in WP General Settings), this is a one-click account. On enterprise sites with registration disabled and SSO-gated logins, this step alone eliminates the vulnerability.- Target site runs WordPress with the Avada theme and Fusion Builder ≤ 3.15.1
- Attacker can create or acquire a Subscriber (or higher) account
- Most B2B / marketing sites disable public registration
- Sites behind SSO / VPN / IP allowlist are not reachable to arbitrary attackers
Enumerate post IDs with dynamic-data-bearing content
/wp-json/wp/v2/posts, and archive pages. Tools: wpscan --enumerate p, feroxbuster, or a curl loop against /?p=<id>. This step has zero friction and no detection signal on a typical site.- Site exposes the standard REST API or public post archives
- None meaningful — WP defaults expose post enumeration
Invoke Fusion Builder Dynamic Data with an underscore-prefixed key
fusion_get_post_custom_field() with post_custom_field=_wc_order_key, _billing_email, _edd_payment_meta, _license_key, or any other guessed protected meta key. Because the function skips the is_protected_meta() check, the value is returned in the rendered fragment. PoC scripts have been published against the post_custom_field parameter shape.- Valid nonce/cookie from the authenticated Subscriber session
- Target post carries the guessed protected meta key
- Attacker must guess or dictionary-attack meta key names — no listing primitive
- Sites that don't run WooCommerce / EDD / LMS have little sensitive
_metato leak
fusion_get_post_custom_field calls after the April 2026 rule push.Chain leaked data into follow-on abuse
- Sensitive PII / tokens actually stored in protected meta
- Downstream systems that trust those secrets
- Modern WooCommerce stores tokenize payment data via gateways (Stripe, Braintree) — raw card data is not in post meta
- GDPR/PCI-aware operators minimize what lives in
_meta
The supporting signals.
| In-the-wild status | No confirmed exploitation. Not tracked in CISA KEV. No campaigns reported by Wordfence, Sucuri, or Patchstack as of July 2026. |
|---|---|
| Proof-of-concept | Public technical writeups on wp-firewall.com and managed-wp.com. Trivial curl-based PoC — a shell one-liner reproduces it. |
| EPSS | 0.00269 (~19th percentile) — low exploitation likelihood over the next 30 days. |
| KEV status | Not listed on CISA KEV as of 2026-07-15. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N — network, low complexity, low priv required, confidentiality-only, no integrity/availability. |
| Affected versions | Avada (Fusion) Builder ≤ 3.15.1 (all prior releases). |
| Fixed version | 3.15.2 — adds is_protected_meta() guard on the post_custom_field parameter. No distro backports (commercial theme distributed via ThemeForest / ThemeFusion updater). |
| Exposure population | Avada is bundled with the Avada theme (>950k ThemeForest sales lifetime). Publicscanning via WPScan API shows a long tail of unpatched sites, but the *authenticated + registration-enabled* subset is a fraction of that. |
| Disclosure | Published 2026-04-15 (NVD) / 2026-04-22 (GHSA-j7wx-2ff4-pc88). |
| Reporter | Coordinated via Wordfence vulnerability research program. |
noisgate verdict.
Downgraded one notch from vendor MEDIUM to LOW because the single decisive factor is the confidentiality-only, authenticated-Subscriber constraint against a payload that leaks arbitrary post meta only if the site both allows open registration AND stores sensitive data in underscore-prefixed meta. There is no write, no auth bypass, no privilege escalation, and no path to RCE — the worst-case outcome is a privacy incident, not a breach of the host or the WordPress admin plane.
Why this verdict
- Authenticated precondition compresses reachable population — Subscriber capability is required; enterprise-hosted Avada sites overwhelmingly disable public registration or gate it behind CAPTCHA + email verification, cutting the attacker-accessible population dramatically.
- Confidentiality-only, bounded blast radius — the vector is
C:L / I:N / A:N. No write, no code execution, no session forgery. Worst plausible outcome is exposure of order emails, license keys, or plugin scratch fields — a privacy incident on a single site, not fleet compromise. - Role multiplier: low-value role (marketing/CMS tier) — Avada is a *frontend page-builder theme*. Its canonical deployment is marketing/brochure sites, WooCommerce storefronts, and campaign microsites — not an identity provider, hypervisor, PAM, CI/CD, or backup plane. The chain does NOT reach domain/fleet/supply-chain scale in any realistic deployment role, so no HIGH/CRITICAL floor is triggered.
- Role multiplier: typical role (WooCommerce storefront) — the worst-case data leak is customer email / order metadata. Impact is a GDPR-reportable privacy incident scoped to one site's customer list, not multi-tenant compromise. Still bounded within LOW/MEDIUM.
- No wormable, no auth-bypass, no chain to admin — the bug cannot be pivoted into WP admin without a separate privilege-escalation vulnerability. EPSS 0.00269 and no KEV listing corroborate the low weaponization interest.
Why not higher?
MEDIUM would be defensible if Avada sites broadly enabled open registration or if the leak included credentials/tokens usable against WP admin — neither generalizes. The bug cannot write, escalate, or execute; upgrading to HIGH would ignore the confidentiality-only vector and the absence of any exploitation signal.
Why not lower?
IGNORE is wrong because a real information-disclosure primitive exists with a public PoC, and WooCommerce-backed Avada storefronts genuinely store customer PII in post meta. It deserves scheduled patching, not silent acceptance.
What to do — in priority order.
- Disable open user registration site-wide — In *Settings → General*, uncheck Anyone can register. This removes the authenticated precondition for opportunistic attackers. No mitigation SLA applies at LOW severity, but this is a five-second change worth making today on any Avada site that doesn't need self-service accounts.
- Deploy the Wordfence / Patchstack virtual patch rule for CVE-2026-1541 — Both vendors shipped WAF signatures in late April 2026 that block
post_custom_fieldvalues starting with_. Apply within your normal WAF rule-update cadence — no mitigation SLA at LOW, but it costs nothing if you already run one of these WAFs. - Audit protected post meta for sensitive content — Run
wp db query "SELECT DISTINCT meta_key FROM wp_postmeta WHERE meta_key LIKE '\_%'"and identify keys carrying PII, license keys, or tokens. Where feasible, move secrets out of post meta into a dedicated encrypted store. This is defense-in-depth beyond CVE-2026-1541. - Upgrade Fusion Builder to ≥ 3.15.2 during the next scheduled CMS window — This is the definitive remediation. Push via your normal WordPress plugin-update process; regression risk is minimal (the patch is a single
is_protected_meta()guard). Target the noisgate remediation SLA of ≤ 365 days for LOW verdicts.
- MFA on WordPress logins — the attacker only needs a valid Subscriber session, which they can create legitimately via self-registration; MFA on their own attacker-owned account does not protect the site.
- Removing the Fusion Builder Dynamic Data UI from admin views — the vulnerable code path is invoked server-side via the AJAX/preview endpoint, not gated by the admin UI being visible.
- Network-layer segmentation of the WP host — the vuln is
AV:Nand reached through the normal public HTTPS front door; internal segmentation does not change reachability.
Crowdsourced verification payload.
Run this from an auditor workstation with curl and jq installed. It probes the Fusion Builder plugin readme for its declared version — no auth required, no exploit sent. Invoke as ./check-cve-2026-1541.sh https://target-site.example.com. No elevated privileges needed.
#!/usr/bin/env bash
# check-cve-2026-1541.sh — Avada Fusion Builder version check for CVE-2026-1541
# Exit: 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN
set -u
if [ $# -lt 1 ]; then
echo "usage: $0 <https://target-site>" >&2
exit 2
fi
TARGET="${1%/}"
FIXED="3.15.2"
UA="noisgate-cve-2026-1541-check/1.0"
# Candidate readme locations shipped by Fusion Builder
PATHS=(
"/wp-content/plugins/fusion-builder/readme.txt"
"/wp-content/plugins/fusion-builder/fusion-builder.php"
)
version=""
for p in "${PATHS[@]}"; do
body=$(curl -sk -A "$UA" --max-time 10 "${TARGET}${p}" || true)
# readme.txt: 'Stable tag: 3.15.1' plugin header: 'Version: 3.15.1'
v=$(printf '%s\n' "$body" | grep -Ei '^(Stable tag|Version)[[:space:]]*:' | head -1 | awk -F: '{print $2}' | tr -d ' \r')
if [ -n "$v" ]; then version="$v"; break; fi
done
if [ -z "$version" ]; then
echo "UNKNOWN — Fusion Builder readme not reachable at ${TARGET}"
exit 2
fi
# semver-ish compare
lower=$(printf '%s\n%s\n' "$version" "$FIXED" | sort -V | head -1)
if [ "$version" = "$FIXED" ] || [ "$lower" = "$FIXED" ]; then
echo "PATCHED — Fusion Builder ${version} (>= ${FIXED})"
exit 0
else
echo "VULNERABLE — Fusion Builder ${version} (< ${FIXED}) — CVE-2026-1541"
exit 1
fi
If you remember one thing.
_meta and open registration, treat it as MEDIUM locally and pull the patch inside 90 days.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.