A PHP type-juggling bug in your front door's lock lets anyone walk in with a bent key
CVE-2026-15981 is an authentication bypass in the miniOrange SAML Single Sign On – SSO Login plugin for WordPress, affecting all versions ≤ 5.4.4 of the Free edition and equivalent versions across six paid editions (Premium ≤ 13.0.3, Standard ≤ 17.0.5, Enterprise ≤ 26.0.2, VIP ≤ 32.0.7, and both Multisite variants). The root cause is a classic PHP type-juggling mistake: openssl_verify() returns a tri-state integer — 1 (valid), 0 (invalid), or -1 (processing error) — but the plugin evaluates the result with a loose boolean check at XMLSecurityKey.php:494. In PHP, -1 is truthy, so a deliberately malformed signature that triggers an OpenSSL error is accepted as *valid*. An unauthenticated attacker sends a crafted SAMLResponse with a garbage signature and an attacker-controlled NameID pointing at the admin account; the plugin calls wp_set_auth_cookie() and hands over the session.
The vendor's CVSS 9.8 CRITICAL rating is accurate and if anything understates urgency given real-world conditions. This is not a theoretical risk: as of August 2026 active exploitation has been confirmed, with attackers chaining CVE-2026-15981 with a companion flaw (CVE-2026-61979, an HMAC algorithm-confusion bug in the same plugin) to forge complete SAML responses. A public proof-of-concept exists on GitHub targeting the Free edition, and scanning from at least six IPs across four countries has been observed. The plugin is an identity/authentication gateway — its entire purpose is to be the trust boundary — and a bypass here grants full WordPress admin, including the ability to install backdoor plugins, exfiltrate data, or pivot to the hosting infrastructure.
5 steps from start to impact.
Identify target running miniOrange SAML SSO
/wp-login.php?option=saml_user_login or the ACS URL configured in the plugin). The plugin slug miniorange-saml-20-single-sign-on is also visible in page source or via WPScan enumeration. Shodan/FOFA/Censys dorks for miniOrange SAML endpoints are trivial to construct.- Target WordPress site is publicly accessible
- miniOrange SAML SSO plugin is installed and active
- Only ~30,000 customers use this plugin family — small fraction of all WordPress sites
Craft malformed SAMLResponse with garbage signature
SAMLResponse XML document with a NameID set to the target admin's email or username. The SignatureValue is deliberately malformed — e.g., non-base64 garbage or a truncated value — so that openssl_verify() returns -1 (error) rather than 0 (invalid). The public PoC automates this step. No IdP credentials, certificates, or secrets are needed.- Knowledge of at least one valid WordPress username or email (often
admin) - No authentication required
- None — default WordPress installs expose author usernames via REST API or author archives
SAMLResponse parameters with malformed XML signatures can flag this, but most generic WAFs do not inspect SAML payloads.Submit SAMLResponse to ACS endpoint
mo_saml_validate_signature() calls openssl_verify(), receives -1, evaluates it as truthy via loose comparison, and accepts the assertion as legitimately signed. The NameID is extracted and matched to a WordPress user account.- ACS endpoint is reachable (it is, by design, on the public login page)
- None — the endpoint must be publicly reachable for SAML to function
openssl_verify returning -1) would catch this, but the plugin does not log this by default.Admin session cookie issued
wp_set_auth_cookie() for the targeted user account (typically the site administrator). The attacker receives a valid wordpress_logged_in_* cookie and is redirected to /wp-admin. From this point the attacker has full WordPress admin privileges: plugin installation, theme editing (PHP code execution), user management, and database access via plugins like WP-CLI or Adminer.- Targeted username/email exists in WordPress user table
- None
Post-exploitation: backdoor installation and lateral movement
wp-config.php (database credentials, API keys, SMTP passwords), pivoting to the database server, or attacking other sites on the same hosting account. In enterprise environments where WordPress hosts an internal portal, the compromised server becomes a beachhead for lateral movement.- WordPress admin access (achieved in step 4)
- Hardened hosting environments may restrict file writes or plugin uploads
- Container-based WordPress deployments may limit persistence
The supporting signals.
| In-the-Wild Exploitation | Active. BleepingComputer confirmed exploitation attempts from six IPs across Belgium, Nigeria, US, and Germany as of August 24, 2026. DigitalOcean blocked an anomalous admin session on August 16 traced to this chain. Attackers are chaining CVE-2026-15981 with CVE-2026-61979 for full SAML forgery. |
|---|---|
| Proof-of-Concept | Public. A PoC targeting the Free edition is available on GitHub. Researcher Supakiad S. (m3ez) is credited with discovery. The exploit is straightforward — a single crafted HTTP POST. |
| EPSS | 0.00815 (≈ top 8–10% of all CVEs). Given confirmed exploitation, EPSS likely lags reality here. |
| KEV Status | Not yet listed as of 2026-08-26. Given active exploitation, KEV addition is probable in coming days. |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — Network-accessible, no privileges, no interaction, full CIA impact. Every sub-metric is worst-case. |
| Affected Versions | Free ≤ 5.4.4, Premium ≤ 13.0.3, Standard ≤ 17.0.5, Enterprise ≤ 26.0.2, VIP ≤ 32.0.7, Premium Multisite ≤ 20.2.7, VIP Multisite ≤ 35.0.6 — seven distinct version lines under one plugin slug. |
| Fixed Versions | Free 5.4.5, Premium 13.0.4, Standard 17.0.6, Enterprise 26.0.3, VIP 32.0.8, Premium Multisite 20.2.8, VIP Multisite 35.0.7. Released July 2026. |
| Exposure Data | miniOrange reports ~30,000 customers across the plugin family. The Free edition alone shows 10,000+ active installs on wordpress.org. Enterprise/VIP editions are not tracked publicly but are used in corporate SSO deployments. |
| Disclosure Date | 2026-07-23 (Patchstack advisory). Patches released concurrently. Exploitation observed starting ~August 16, 2026. |
| Discoverer | Supakiad S. (m3ez), credited via Patchstack's coordinated disclosure program. |
noisgate verdict.
The single most decisive factor is that this is an unauthenticated remote authentication bypass in an identity/authentication gateway component with confirmed active exploitation and a public PoC. The plugin's sole purpose is to be the SSO trust boundary — a bypass here is definitionally a complete security failure of the component, and the chain requires zero privileges, zero user interaction, and is already being weaponized in the wild.
Why this verdict
- Unauthenticated remote, zero-click: The entire attack is a single POST request to a publicly accessible endpoint. No credentials, no phishing, no user interaction. Every sub-metric of the CVSS vector is worst-case. No friction-based downgrade is warranted for attack complexity.
- Active exploitation confirmed: Attacks observed in the wild since at least August 16, 2026, with scanning from multiple countries. A public PoC exists on GitHub. This is not theoretical — defenders are already behind the curve.
- Public PoC lowers the bar: The exploit is a single crafted HTTP POST. The type-juggling bug is trivially reproducible. Script-kiddie-grade exploitation is realistic.
- Role multiplier: The miniOrange SAML SSO plugin is an identity/authentication gateway by definition — it exists solely to control who gets authenticated. In enterprise deployments, WordPress sites behind SAML SSO are typically corporate intranets, customer portals, or partner-facing applications holding sensitive data. A bypass of this component grants admin-level access to the WordPress instance, enabling PHP code execution on the web server (blast radius: host → potentially lateral movement to database tier and shared hosting neighbors). For organizations using WordPress as an internal portal, compromise can yield credential material (SMTP, DB, API keys in
wp-config.php) useful for further lateral movement. Because the component IS the auth boundary (≥95% of installs occupy the identity-gateway role by definition), the verdict floor is CRITICAL. - Seven edition version lines create patching confusion: Vulnerability databases initially only covered the Free edition. Paid edition customers may believe they are unaffected when they are not. This operational gap increases real-world exposure duration.
Why not higher?
The score is already near-maximum at 9.6. A full 10.0 would require wormable or self-propagating characteristics, which this does not have — each target must be individually exploited. The install base of ~30,000 customers, while significant, is small relative to WordPress's overall footprint, limiting the total blast radius across the internet.
Why not lower?
Every downgrade pressure point fails to materialize: the attack is unauthenticated (no prior access needed), the endpoint is public by design (SAML ACS must be reachable), the exploit is trivial (single POST), exploitation is already happening in the wild, and the affected component is literally the authentication layer. There is no friction to justify any downgrade. Dropping below CRITICAL would require evidence that the exploit doesn't work reliably or that the exposed population is negligible — neither is true.
What to do — in priority order.
- Disable the miniOrange SAML SSO plugin immediately if not business-critical — If SAML SSO can be temporarily replaced with native WordPress authentication or another SSO plugin, deactivating miniOrange eliminates the attack surface entirely. This is the fastest mitigation — deploy within the 3-day noisgate mitigation SLA for CRITICAL findings.
- Apply the one-line source code hotfix to XMLSecurityKey.php — If you cannot update to the patched version immediately, change the
openssl_verify()return check at line 494 ofXMLSecurityKey.phpfrom a loose boolean evaluation to a strict=== 1comparison:return openssl_verify($ql, $hl, $this->key, $MG) === 1;This neutralizes the tri-state bug. Deploy within 3 days. - Block HMAC-SHA1 signature algorithm in Utilities.php — To also neutralize the companion CVE-2026-61979, add a check after line 246 of
Utilities.phpto rejectHMAC_SHA1as aSignatureMethod. This prevents the algorithm-confusion attack that is being chained with CVE-2026-15981 in the wild. Deploy within 3 days. - WAF rule to inspect and block malformed SAMLResponse payloads — Deploy a WAF rule on the ACS endpoint URL that rejects POST requests where the
SAMLResponseparameter contains aSignatureValuethat fails base64 decoding or is suspiciously short/malformed. This is a defense-in-depth layer, not a primary fix. ModSecurity or Cloudflare custom rules can implement this. - Monitor for anomalous WordPress admin sessions — Alert on
wp_loginevents for administrator accounts that do not correlate with a legitimate IdP-side authentication event. Check server access logs for POST requests to the ACS endpoint followed by/wp-adminaccess from the same IP. Use WP Activity Log or Sucuri plugin.
- IP-based blocking of known attacker IPs — The six IPs reported in current campaigns will rotate. Attackers use commodity VPS infrastructure. IP blocking is whack-a-mole and provides only hours of coverage.
- WordPress application-level passwords / 2FA on wp-login.php — The SAML bypass occurs *before* WordPress's native authentication layer. The plugin directly calls
wp_set_auth_cookie()after accepting the forged assertion, bypassing any 2FA plugins that hook into the standard login flow. - Restricting XML entity expansion (XXE protections) — This is not an XXE vulnerability. The XML is parsed normally; the flaw is in signature verification logic.
libxml_disable_entity_loader()does nothing here.
Crowdsourced verification payload.
Run this script on each WordPress host (or from a management server with filesystem access to WordPress installations). Invoke as bash check_cve_2026_15981.sh /var/www/html where the argument is the WordPress root directory. Requires read access to the plugin directory. No WordPress admin credentials needed.
#!/usr/bin/env bash
# check_cve_2026_15981.sh — Detect miniOrange SAML SSO auth bypass (CVE-2026-15981)
# Usage: bash check_cve_2026_15981.sh /path/to/wordpress
# Exit codes: 0 = PATCHED or not installed, 1 = VULNERABLE, 2 = UNKNOWN
set -euo pipefail
WP_ROOT="${1:?Usage: $0 /path/to/wordpress}"
PLUGIN_DIR="$WP_ROOT/wp-content/plugins/miniorange-saml-20-single-sign-on"
if [ ! -d "$PLUGIN_DIR" ]; then
echo "NOT INSTALLED — miniOrange SAML SSO plugin not found in $PLUGIN_DIR"
exit 0
fi
# Check for the vulnerable loose boolean check in XMLSecurityKey.php
XML_SEC_FILE="$PLUGIN_DIR/includes/lib/SAML2Core/XMLSecurityKey.php"
if [ ! -f "$XML_SEC_FILE" ]; then
# Try alternative paths used in different editions
XML_SEC_FILE=$(find "$PLUGIN_DIR" -name 'XMLSecurityKey.php' -type f 2>/dev/null | head -1)
fi
if [ -z "$XML_SEC_FILE" ] || [ ! -f "$XML_SEC_FILE" ]; then
echo "UNKNOWN — Could not locate XMLSecurityKey.php"
exit 2
fi
# The vulnerable pattern: openssl_verify result used in loose boolean context
# The patched version uses === 1 strict comparison
if grep -qP 'openssl_verify\s*\(' "$XML_SEC_FILE"; then
if grep -qP '===\s*1' "$XML_SEC_FILE"; then
echo "PATCHED — XMLSecurityKey.php uses strict === 1 comparison for openssl_verify()"
exit 0
else
echo "VULNERABLE — XMLSecurityKey.php uses loose boolean check on openssl_verify() return value (CVE-2026-15981)"
# Also extract version for reporting
MAIN_FILE=$(find "$PLUGIN_DIR" -maxdepth 1 -name '*.php' -exec grep -l 'Plugin Name' {} \; 2>/dev/null | head -1)
if [ -n "$MAIN_FILE" ]; then
VER=$(grep -oP 'Version:\s*\K[0-9.]+' "$MAIN_FILE" 2>/dev/null || echo 'unknown')
echo " Installed version: $VER"
fi
exit 1
fi
else
echo "UNKNOWN — openssl_verify() call not found in $XML_SEC_FILE; unexpected plugin structure"
exit 2
fiIf you remember one thing.
=== 1 hotfix to XMLSecurityKey.php, or update to the patched version (Free 5.4.5, Premium 13.0.4, Standard 17.0.6, Enterprise 26.0.3, VIP 32.0.8, or the corresponding Multisite versions). Given active exploitation, do not wait — treat this as a same-day emergency. The noisgate remediation SLA is ≤ 90 days for the full vendor patch, but in practice you should complete remediation this week. Pay special attention to paid editions: vulnerability databases initially missed them, so your scanner may report a false negative. Verify manually using the provided script. Also audit WordPress admin session logs for any logins that did not originate from your IdP — if you find any, assume full site compromise and initiate IR.Sources
- Patchstack — One slug, seven editions: the miniOrange SAML SSO bug
- BleepingComputer — Hackers target WordPress sites in miniOrange auth bypass attacks
- The Hacker News — Attackers Target miniOrange SAML Flaws
- Patchstack Database — CVE-2026-15981
- GitHub Advisory — GHSA-wgjx-q85h-87v2
- NVD — CVE-2026-15981
- THREATINT — CVE-2026-15981
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.