CVE-2026-18315 is a critical, network-exploitable authorization bypass in the TrueBooker – Appointment Booking and Scheduler System plugin for WordPress. All versions up to and including 1.2.6 are affected. The plugin exposes an AJAX handler, admin_user_create_cus, that fails to authenticate the caller or verify WordPress capabilities before trusting the truebooker_wp_user_id parameter and passing it to wp_update_user. In practical terms, an unauthenticated attacker can rewrite the email address of an arbitrary WordPress user, including an administrator, then use the normal WordPress lost-password flow to complete account takeover.
This is not a theoretical hardening issue. The vulnerable code path is reachable over the network without credentials, the prerequisite knowledge is limited to a valid target user ID or login enumeration, and WordPress provides the second half of the intrusion chain for free through wp-login.php?action=lostpassword. Defenders should assume scanning began quickly after disclosure and prioritize internet-facing WordPress sites that run booking, scheduling, clinic, salon, services, or appointment workflows.
Affected Products and Risk
- Product: TrueBooker – Appointment Booking and Scheduler System plugin for WordPress
- Affected versions: all versions up to and including 1.2.6
- CVE: CVE-2026-18315
- CVSS: 9.8 Critical
- Attack vector: network, unauthenticated
- Impact: arbitrary WordPress user email overwrite, administrator account takeover, site compromise, likely content injection, credential harvesting, persistence through rogue admin users, and downstream customer data exposure.
The root cause is an authorization bypass through a user-controlled key. The handler accepts an attacker-supplied WordPress user identifier and performs a privileged update operation without confirming that the requester is logged in, has a valid nonce, or holds a capability such as manage_options or edit_users. The dangerous object is not merely the plugin endpoint; it is the combination of admin-ajax.php, wp_update_user, WordPress email uniqueness behavior, and the self-service password reset workflow.
A defensible exploitation model is:
- Attacker enumerates or guesses a target account, commonly the administrator account with user ID 1 or a login such as
admin. - Attacker sends an unauthenticated request to
/wp-admin/admin-ajax.phpwithaction=admin_user_create_cusand a craftedtruebooker_wp_user_id. - The plugin updates that user's email address to an attacker-controlled mailbox.
- Attacker submits the standard lost-password form for the targeted login.
- WordPress mails the reset link to the attacker-controlled address.
- Attacker resets the password, logs in, and establishes persistence by creating additional administrators, installing malicious plugins or themes, editing files, or adding OAuth/API integrations.
The summary does not state a confirmed in-the-wild campaign, public proof of concept, or CISA Known Exploited Vulnerabilities listing. Treat that as absence of evidence in the source item, not evidence of safety. The barrier to weaponization is low, and WordPress plugin CVEs are routinely harvested by scanners within hours of NVD publication.
Immediate Defensive Actions
If you run TrueBooker, assume exposure until proven otherwise. Take these steps in order:
- Inventory every WordPress instance, including staging, marketing microsites, multisite networks, forgotten subdomains, and customer-hosted booking portals.
- Identify TrueBooker installations and versions. Any version at or below 1.2.6 is vulnerable.
- If a vendor-fixed release is available and verified, update immediately and confirm the installed version is no longer in the affected range. Do not assume a specific fixed version beyond the vendor advisory; validate from the WordPress plugin repository or vendor changelog before change windows.
- If you cannot verify a fixed release, deactivate and remove the plugin now. Booking downtime is preferable to unauthenticated administrator takeover.
- Force password resets for all administrator and privileged users after remediation. Rotate API keys, application passwords, SMTP credentials, payment gateway secrets, and any integrations stored in wp-config or plugin settings.
- Review users, sessions, scheduled posts, options, autoloaded options, mu-plugins, themes, and recently modified PHP files for persistence.
- Preserve logs before rotation. Capture web access logs, WordPress audit logs, authentication logs, PHP-FPM logs, and host file timelines for the exposure window.
Detection and Response
Prioritize high-fidelity signals around the exact vulnerable path, then correlate with password reset and post-compromise behavior. A single request to admin_user_create_cus from an internet source is suspicious on many sites; a follow-on lost-password request for an administrator from the same source is an incident until disproven.
---
title: CVE-2026-18315 TrueBooker Unauthenticated AJAX User Update Attempt
id: 3f7f6b21-8f6a-4d2b-9b19-7c1b9a2d4e10
status: experimental
description: Detects network requests to the vulnerable TrueBooker WordPress AJAX action that passes a user-controlled ID into a privileged user update path without authentication.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-18315
author: Security Arsenal
date: 2026/01/15
tags:
- attack.initial_access
- attack.privilege_escalation
- attack.t1190
logsource:
category: webserver
detection:
selection_method:
cs-method: 'POST'
selection_endpoint:
cs-uri-stem|endswith: '/wp-admin/admin-ajax.php'
selection_action:
cs-uri-query|contains:
- 'action=admin_user_create_cus'
- 'truebooker_wp_user_id'
selection_body:
cs-body|contains:
- 'action=admin_user_create_cus'
- 'truebooker_wp_user_id'
condition: selection_method and selection_endpoint and (selection_action or selection_body)
falsepositives:
- Rare legitimate plugin administrative traffic from authenticated wp-admin sessions; validate source IP, cookie presence, response status, and same-origin nonce behavior.
level: critical
---
title: WordPress Administrator Lost Password Reset After Suspicious AJAX Activity
id: 9d4f5f2e-51f2-4b08-b6ef-2d3a7f9c8b44
status: experimental
description: Detects password reset attempts against privileged WordPress accounts that may complete account takeover after an email overwrite. Use as a correlation signal with web access and WordPress audit logs.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-18315
author: Security Arsenal
date: 2026/01/15
tags:
- attack.credential_access
- attack.persistence
- attack.t1078
logsource:
category: webserver
detection:
selection_method:
cs-method: 'POST'
selection_endpoint:
cs-uri-stem|endswith: '/wp-login.php'
selection_reset:
cs-uri-query|contains:
- 'action=lostpassword'
- 'action=resetpass'
- 'action=rp'
selection_admin_target:
cs-body|contains:
- 'user_login=admin'
- 'user_login=administrator'
- 'user_login=root'
condition: selection_method and selection_endpoint and selection_reset and selection_admin_target
falsepositives:
- Legitimate administrator password resets; reduce noise by requiring prior CVE-2026-18315 AJAX hits, unusual ASN, hosting provider source, or reset outside change windows.
level: high
let lookback = 14d;
let suspicious_ajax = Syslog
| where TimeGenerated >= ago(lookback)
| where SyslogMessage has '/wp-admin/admin-ajax.php'
| where SyslogMessage has 'admin_user_create_cus' or SyslogMessage has 'truebooker_wp_user_id'
| extend SourceIP = extract(@'src=([0-9a-fA-F:.]+)|client=([0-9a-fA-F:.]+)|^([0-9]{1,3}(\.[0-9]{1,3}){3})', 1, SyslogMessage)
| project AjaxTime=TimeGenerated, Computer, SourceIP, SyslogMessage;
let resets = Syslog
| where TimeGenerated >= ago(lookback)
| where SyslogMessage has '/wp-login.php'
| where SyslogMessage has 'action=lostpassword' or SyslogMessage has 'action=resetpass' or SyslogMessage has 'action=rp'
| extend SourceIP = extract(@'src=([0-9a-fA-F:.]+)|client=([0-9a-fA-F:.]+)|^([0-9]{1,3}(\.[0-9]{1,3}){3})', 1, SyslogMessage)
| project ResetTime=TimeGenerated, Computer, SourceIP, SyslogMessage;
suspicious_ajax
| join kind=inner resets on Computer, SourceIP
| where ResetTime between (AjaxTime .. AjaxTime + 30m)
| summarize FirstAjax=min(AjaxTime), LastReset=max(ResetTime), Hits=count() by Computer, SourceIP
| order by Hits desc;
-- Find TrueBooker plugin code and recently modified PHP artifacts in likely web roots and upload paths
LET candidate_globs = [
'/var/www/**/wp-content/plugins/**/truebooker*/**/*.php',
'/var/www/**/wp-content/plugins/**/appointment*/**/*.php',
'/var/www/**/wp-content/uploads/**/*.php',
'/home/**/public_html/wp-content/plugins/**/truebooker*/**/*.php',
'/home/**/public_html/wp-content/uploads/**/*.php'
]
SELECT FullPath, Size, Mtime, Btime,
iff(condition=FullPath =~ 'uploads', then='PHP_IN_UPLOADS_REVIEW', else='PLUGIN_CODE_REVIEW') AS ReviewClass
FROM foreach(row=candidate_globs,
query={
SELECT FullPath, Size, Mtime, Btime
FROM glob(globs=row._value)
})
WHERE Mtime > ago(days=30)
ORDER BY Mtime DESC
#!/usr/bin/env bash
set -euo pipefail
# Run from the WordPress document root or pass paths as arguments.
# Purpose: identify affected TrueBooker installs, disable the plugin if WP-CLI is available, and preserve evidence.
ROOTS="${@:-/var/www /home}"
EVIDENCE_DIR="/var/tmp/cve-2026-18315-$(date +%Y%m%d%H%M%S)"
mkdir -p "$EVIDENCE_DIR"
echo '[+] Collecting web access log candidates'
find /var/log/apache2 /var/log/nginx /var/log/httpd -type f \( -name '*access*log*' -o -name '*.log' \) 2>/dev/null | while read -r f; do
cp -a "$f" "$EVIDENCE_DIR/" 2>/dev/null || true
done
echo '[+] Searching for TrueBooker plugin directories'
find $ROOTS -type d -path '*/wp-content/plugins/*' \( -iname '*truebooker*' -o -iname '*appointment*booking*' \) 2>/dev/null | tee "$EVIDENCE_DIR/plugin-dirs.txt"
while read -r dir; do
[ -d "$dir" ] || continue
echo "[+] Candidate plugin: $dir"
grep -Rni --include='*.php' -E 'admin_user_create_cus|truebooker_wp_user_id|wp_update_user' "$dir" 2>/dev/null | tee -a "$EVIDENCE_DIR/code-indicators.txt" || true
find "$dir" -maxdepth 2 -type f \( -name 'readme.txt' -o -name '*.php' \) -print0 | xargs -0 grep -Hi -E 'Version:|Stable tag:' 2>/dev/null | tee -a "$EVIDENCE_DIR/versions.txt" || true
wp_root="${dir%%/wp-content/plugins/*}"
if command -v wp >/dev/null 2>&1; then
(cd "$wp_root" && wp plugin list --format=csv --allow-root 2>/dev/null | tee -a "$EVIDENCE_DIR/wp-plugin-list-$(echo "$wp_root" | tr '/ ' '__').csv" || true)
(cd "$wp_root" && wp plugin deactivate --all --allow-root --skip-plugins --skip-themes 2>/dev/null | tee -a "$EVIDENCE_DIR/wp-cli-deactivate.log" || true)
fi
done < "$EVIDENCE_DIR/plugin-dirs.txt"
echo '[+] Searching logs for vulnerable action and password reset correlation'
grep -RniE 'admin-ajax\.php|admin_user_create_cus|truebooker_wp_user_id|wp-login\.php\?action=lostpassword|action=resetpass' /var/log/apache2 /var/log/nginx /var/log/httpd 2>/dev/null | tee "$EVIDENCE_DIR/log-indicators.txt" || true
echo '[+] Listing privileged WordPress users where WP-CLI is available'
find $ROOTS -type f -name wp-config.php 2>/dev/null | while read -r cfg; do
wp_root="$(dirname "$cfg")"
if command -v wp >/dev/null 2>&1; then
(cd "$wp_root" && wp user list --role=administrator --fields=ID,user_login,user_email,user_registered,user_status --format=csv --allow-root 2>/dev/null | tee -a "$EVIDENCE_DIR/admins-$(echo "$wp_root" | tr '/ ' '__').csv" || true)
fi
done
echo "[+] Evidence bundle: $EVIDENCE_DIR"
echo '[!] If any version is <= 1.2.6 or fixed status is unknown, remove the plugin, reset privileged credentials, rotate secrets, and review persistence before restoring service.'
Incident Response Triage Questions
If the KQL or log review shows a hit, answer these questions before closing as benign:
- Did the request to
admin-ajax.phpinclude cookies or a valid WordPress nonce, or was it anonymous? - Was the HTTP response 200 with evidence that a user record changed, rather than a 400/403 plugin rejection?
- Did the same source IP request
wp-login.phpwith a lost-password or reset action within minutes? - Did any administrator email address change unexpectedly in the
wp_userstable or WordPress audit log? - Were new administrator accounts, application passwords, REST API tokens, SMTP settings, or scheduled tasks created after the event?
- Were PHP files introduced under
wp-content/uploads, cache directories, or theme folders that normally contain only static assets?
Treat confirmed email change plus reset activity as full site compromise. WordPress administrator control usually means database content control, plugin/theme code execution through the editor or uploads, and access to customer PII collected by booking workflows.
Remediation and Hardening
- Remove exposure first: update only to a vendor-verified fixed release; otherwise deactivate and delete TrueBooker. Do not rely on hiding
admin-ajax.php; WordPress core and many plugins require it. - Enforce strong admin hygiene: unique administrator usernames, phishing-resistant MFA where the stack supports it, least-privilege roles, and removal of unused accounts.
- Disable file editing in wp-admin with
DISALLOW_FILE_EDITand considerDISALLOW_FILE_MODSon production sites where deployment is pipeline-driven. - Restrict execution in upload and cache directories using web server rules; PHP under
wp-content/uploadsshould be treated as hostile by default. - Add WAF/virtual patch logic only as a temporary bridge: block unauthenticated POSTs to
/wp-admin/admin-ajax.phpcontainingaction=admin_user_create_cusortruebooker_wp_user_id, while logging bypass attempts. Test carefully because other plugins useadmin-ajax.phplegitimately. - Alert on administrator email changes, user role changes, new administrator creation, application password creation, and lost-password storms targeting privileged logins.
- Rotate secrets after remediation: administrator passwords, application passwords, database credentials if wp-config was exposed, SMTP/API keys, payment gateway tokens, calendar integrations, and any third-party booking connectors.
- Review NIST CSF Recover/Respond evidence handling and CIS Control alignment: asset inventory for plugins, secure configuration for web servers, audit log management, and account management.
Official reference: https://nvd.nist.gov/vuln/detail/CVE-2026-18315. Validate fixed-version status through the WordPress plugin repository or vendor advisory before declaring closure, and document whether the plugin was removed, patched, or virtually patched with compensating controls.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.