It is like letting any gym member walk behind the reception desk and turn off the appointment-confirmation checkbox
CVE-2026-11887 is a missing-authorization flaw in the Salon Booking System WordPress plugin (all versions before 10.30.20). The plugin exposes an AJAX endpoint called SetDefaultBookingStatus that is meant to let an administrator choose whether new bookings require manual approval. Because the handler never checks current_user_can(), any authenticated WordPress user — including a basic *Subscriber* — can POST to that endpoint and flip the setting so that all future bookings are auto-confirmed. The bug carries CWE-862 (Missing Authorization) and was reported by researcher kevin(@OPCIA) via WPScan.
The vendor-assigned CVSS of 4.3 MEDIUM is technically defensible on a pure-vector reading (network, low complexity, low privilege, integrity-only), but in practice it overstates the real-world risk. The impact is limited to a single boolean setting that controls booking approval — there is no path to data exfiltration, privilege escalation to admin, file upload, or code execution. The plugin itself has roughly 2,000 active installations worldwide, all of them small-business salon and spa sites. No confidentiality or availability impact exists, no exploit code is circulating, EPSS sits at the 0.28th percentile, and CISA has not added it to KEV. For an enterprise fleet, this CVE is background noise.
3 steps from start to impact.
Obtain subscriber-level WordPress credentials
- WordPress user registration is enabled, OR attacker already has credentials
- Target site runs Salon Booking System < 10.30.20
- Many small salon sites disable self-registration and handle bookings as guest checkout
- Brute-forcing WordPress logins is widely blocked by rate-limiting plugins (Wordfence, Limit Login Attempts) and WAFs
Send POST to SetDefaultBookingStatus AJAX endpoint
admin-ajax.php POST request with action=SetDefaultBookingStatus and the desired approval value. Because the handler does not verify current_user_can('manage_options') or any other capability, WordPress processes the request. This is a single HTTP request — no chaining or timing is required.- Valid WordPress session cookie or nonce
- Knowledge of the AJAX action name (trivially discoverable from the plugin's JavaScript files)
- WAFs with WordPress-specific rulesets (Wordfence premium, Patchstack) can block unexpected
admin-ajax.phpactions from low-privilege roles - The action name must be known, though it is visible in the plugin's front-end JS
admin-ajax.php calls; Wordfence real-time firewall rules for Salon Booking System.Booking approval is bypassed — bookings auto-confirm
- Step 2 succeeded
- Salon staff notice unexpected bookings in their calendar almost immediately
- The setting change is visible in the plugin's admin panel — any admin visit to the settings page will reveal the tampering
SetDefaultBookingStatus handler. Given the LOW verdict, no noisgate mitigation SLA applies — treat this as backlog hygiene and patch during your next scheduled WordPress maintenance window.Settings → General → Anyone can register), disabling it removes the easiest path for an external attacker to obtain Subscriber credentials. This eliminates step 1 of the attack path for unauthenticated outsiders.admin-ajax.php calls to Salon Booking System endpoints. This stops step 2 even if the attacker has credentials.- Network segmentation / firewall rules — The attack travels over standard HTTPS to
wp-admin/admin-ajax.php, the same endpoint used by every WordPress AJAX call. You cannot block it at the network layer without breaking the plugin entirely. - MFA on WordPress admin — MFA protects admin-level logins but does not prevent a Subscriber (who has already authenticated) from issuing the malicious AJAX call. The flaw is authorization, not authentication.
The supporting signals.
| In-the-Wild Exploitation | None observed. Not listed in CISA KEV. No campaigns or threat-actor reporting reference this CVE. |
|---|---|
| Proof-of-Concept | No public PoC found. Checked pocindex.io, GitHub (CVE-2026-11887), ExploitDB — no repos, no templates, no writeups. The exploit is trivial (single POST), but nobody has bothered to publish one. |
| EPSS | 0.00284 (0.28th percentile) — bottom of the probability distribution. FIRST's model sees virtually no exploitation likelihood. |
| KEV Status | Not listed. No CISA Binding Operational Directive applies. |
| 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 privilege required. No confidentiality or availability impact. Integrity impact is Low (a single boolean setting). |
| Affected Versions | Salon Booking System < 10.30.20 (all prior versions). |
| Fixed Version | 10.30.20 (released before July 2026 disclosure). Current latest is 10.31.7. |
| Installed Base | ~2,000 active WordPress installations per wordpress.org. Niche salon/spa/barber plugin. Negligible enterprise footprint. |
| Disclosure | 2026-07-01 via WPScan. Reported by kevin(@OPCIA). |
| Scanning / Exposure | No GreyNoise tags, no Shodan/Censys/FOFA dorks specific to this plugin's AJAX endpoint. The plugin does not expose a unique fingerprint beyond standard WordPress admin-ajax.php. |
Sources.
Why this verdict
- Authentication required: The attacker must hold at least a Subscriber-level WordPress account. On hardened sites with registration disabled, this prerequisite alone blocks the chain.
- Impact ceiling is a boolean toggle: The only achievable outcome is flipping a booking-approval setting. There is zero path to code execution, data exfiltration, admin takeover, or lateral movement. The CVSS Integrity:Low rating is accurate — and that is the *entire* impact.
- Minuscule installed base: ~2,000 active installs worldwide, exclusively small-business salon and spa sites. The probability of this plugin existing in a 10,000-host enterprise fleet is effectively zero.
- No exploitation interest: EPSS 0.28th percentile, no KEV listing, no PoC published, no threat-actor reporting. Nobody is weaponizing a booking-approval toggle.
- Role multiplier: Salon Booking System is a front-end scheduling widget for small retail businesses. It does not occupy any high-value deployment role (not identity, not infra, not CI/CD, not database, not edge, not backup, not kernel-mode). The blast radius is confined to the plugin's own booking workflow on a single WordPress site. No floor adjustment applies.
Why not higher?
The vendor's MEDIUM (4.3) already sits at the low end of the medium band, and even that overstates the operational risk. There is no confidentiality or availability impact, the exploit yields only a business-logic setting change, and the plugin's install base is too small to matter at enterprise scale. Upgrading to MEDIUM or above would require either a broader impact (data leak, RCE) or evidence of active exploitation — neither exists.
Why not lower?
A working, unauthenticated bypass or a purely theoretical issue with no demonstrated exploitability would warrant IGNORE. Here, the vulnerability is confirmed, the exploit is trivial for any authenticated user, and it does produce a real (if minor) integrity violation. LOW accurately reflects a confirmed-but-inconsequential flaw.
Crowdsourced verification payload.
Run on any machine with curl and network access to the target WordPress site. Requires no special privileges. Example: bash check_cve_2026_11887.sh https://salon.example.com
#!/usr/bin/env bash
# CVE-2026-11887 — Salon Booking System Booking Approval Bypass Check
# Usage: bash check_cve_2026_11887.sh <wordpress_site_url>
# Checks whether the installed plugin version is below the patched 10.30.20.
# Exit codes: 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN
set -euo pipefail
TARGET="${1:?Usage: $0 <wordpress_site_url>}"
TARGET="${TARGET%/}"
# Attempt to read the plugin's readme.txt for the Stable tag
README_URL="${TARGET}/wp-content/plugins/salon-booking-system/readme.txt"
HTTP_CODE=$(curl -s -o /tmp/sbs_readme.txt -w '%{http_code}' --max-time 10 "$README_URL" 2>/dev/null || echo "000")
if [ "$HTTP_CODE" != "200" ]; then
echo "UNKNOWN — Could not retrieve plugin readme (HTTP $HTTP_CODE). Plugin may not be installed or readme is blocked."
exit 2
fi
VERSION=$(grep -i '^Stable tag:' /tmp/sbs_readme.txt | head -1 | sed 's/[Ss]table tag:[[:space:]]*//' | tr -d '[:space:]')
if [ -z "$VERSION" ]; then
echo "UNKNOWN — readme.txt found but no Stable tag detected."
exit 2
fi
echo "Detected Salon Booking System version: $VERSION"
# Compare versions: vulnerable if < 10.30.20
FIXED="10.30.20"
LOWER=$(printf '%s\n%s' "$VERSION" "$FIXED" | sort -V | head -1)
if [ "$VERSION" = "$FIXED" ] || [ "$LOWER" = "$FIXED" ]; then
echo "PATCHED — Version $VERSION >= $FIXED. CVE-2026-11887 is fixed."
exit 0
else
echo "VULNERABLE — Version $VERSION < $FIXED. CVE-2026-11887 applies."
exit 1
fi