Back to Intelligence

CVE-2026-110653: LatePoint WordPress Plugin OTP Race Condition — Authentication Bypass Detection and Remediation Guide

SA
Security Arsenal Team
October 17, 2026
11 min read

The National Vulnerability Database has published CVE-2026-110653, a CVSS 9.1 (Critical), network-exploitable authentication bypass affecting the Appointment Booking Plugin – LatePoint | Calendar & Scheduling for WordPress in all versions up to and including 5.7.4. The flaw is a textbook time-of-check/time-of-use (TOCTOU) race condition in the plugin's OTP verification logic, and it neutralizes the one control — the 10-attempt lockout — standing between an unauthenticated attacker and OTP-gated customer or administrative accounts.

LatePoint is a widely deployed booking and scheduling component. Sites running it are frequently small-to-mid-sized businesses — clinics, salons, consultancies — that rely on OTP verification as the sole authentication factor for customer portals or staff workflows. If your organization, or any client you manage, exposes a LatePoint booking flow to the internet, treat this as a priority remediation item this week. A CVSS 9.1 rating reflects the reality: the vulnerability is remotely exploitable over the network, requires no authentication, no user interaction, and — unlike most race conditions — the barrier to weaponization is low because the vulnerable primitive is a simple counter increment over HTTP.

Technical Analysis

Affected Products and Versions

  • Product: Appointment Booking Plugin – LatePoint | Calendar & Scheduling for WordPress
  • Affected versions: All versions up to and including 5.7.4
  • Platform: Any WordPress installation running the vulnerable plugin; exploitation is web-server and OS-agnostic (Apache, Nginx, LiteSpeed on Linux are the typical deployment stack)
  • CVE: CVE-2026-110653 | CVSS 3.x: 9.1 (Critical) | Vector: Network
  • Reference: NVD — CVE-2026-110653

Root Cause: Non-Atomic Read-Modify-Write on the Attempts Counter

The defect lives in the plugin's verifyOTP function. The intended control is straightforward: after 10 failed OTP attempts, lock the verification session. The implementation is broken in three compounding ways:

  1. Stale in-memory read. The current attempts counter is read from the database into memory, incremented in PHP, and written back. This is a classic read-modify-write pattern with no atomicity guarantee.
  2. No conditional guard on the UPDATE. The UPDATE statement that persists the incremented counter carries no WHERE attempts < 10 clause, so the database will happily accept the write regardless of how many attempts have already occurred.
  3. No row locking. The code does not use SELECT ... FOR UPDATE (or any equivalent locking primitive) when reading the counter, so there is no serialization between concurrent requests operating on the same OTP session row.

The result is a TOCTOU window: if an attacker fires N concurrent OTP verification requests against the same session before any of them commits its counter update, all N requests read the same pre-lockout counter value (say, 9), all N evaluate as "attempt 10 — still allowed," and all N write back 10. The lockout counter effectively increments by one while the attacker has consumed N guesses. With modest concurrency — even 50–100 parallel requests per batch — an attacker collapses the effective keyspace of a 6-digit OTP from 1,000,000 / 10 ≈ 100,000 lockout-bound sessions down to a handful of racing rounds. This is the same primitive class that made OTP brute-force races in password-reset flows a recurring theme in web app penetration testing throughout 2025 and into 2026.

Exploitation Requirements

  • Network access to the WordPress front end (the plugin's OTP verification endpoint is reachable via WordPress AJAX handlers — typically POST /wp-admin/admin-ajax.php with a LatePoint action parameter, or a plugin-specific REST route)
  • An initiated OTP verification session (trivially obtained by starting a booking/login flow for a target phone number or email)
  • The ability to send concurrent HTTP requests — curl in a loop, a script, or any off-the-shelf HTTP fuzzer

No credentials, no authenticated session, no local foothold. The attack is single-actor, low-cost, and leaves a distinctive signature: burst patterns of OTP verification requests against the same session identifier from a single source.

Exploitation Status

As of publication, CVE-2026-110653 is documented in NVD as a published vulnerability. I have not seen confirmed in-the-wild exploitation reporting or CISA KEV inclusion at the time of writing — but the barrier to a working PoC is low (the technique is well understood by anyone who has tested OTP flows), and WordPress plugin CVEs at this severity historically move from disclosure to mass scanning within days. Assume scanning for the vulnerable version begins immediately, if it hasn't already.

Detection & Response

The defensive opportunity here is genuinely good: race-condition exploitation is noisy by necessity. The attacker cannot avoid sending large bursts of near-simultaneous requests to the same endpoint. That behavior is highly anomalous for a legitimate booking flow, where a human types one OTP and submits it once, maybe twice after a typo. Tune your detections around burst volume, temporal clustering, and OTP session reuse.

Sigma Rules

YAML
---
title: LatePoint OTP Verification Burst - Possible Race Condition Exploitation (CVE-2026-110653)
id: 3f8c2e91-7b4a-4d5e-9f01-6a2b8c4d5e7f
status: experimental
description: Detects high-frequency bursts of OTP verification requests against WordPress AJAX endpoints consistent with TOCTOU race condition exploitation of the LatePoint plugin's attempts counter. Legitimate users submit an OTP once or twice; exploitation requires many concurrent attempts.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-110653
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.credential_access
  - attack.t1110.001
logsource:
  category: webserver
  product: linux
detection:
  selection:
    cs-method: 'POST'
    cs-uri-stem|contains:
      - '/wp-admin/admin-ajax.php'
      - '/wp-json/'
    cs-uri-query|contains:
      - 'latepoint'
      - 'verify_otp'
      - 'verifyotp'
  condition: selection
falsepositives:
  - Legitimate high-traffic booking sites during peak hours (tune with per-IP/per-session thresholds in your SIEM)
  - Load testing or synthetic monitoring of booking flows
level: high
---
title: Repeated Failed Authentication Responses from WordPress OTP Endpoint
id: 8d1e4a72-3c6b-4e7f-a209-9b5d1e6f7a8c
status: experimental
description: Detects a source IP receiving sustained HTTP 200/4xx responses on OTP verification POSTs in a short window, indicative of OTP brute forcing via the LatePoint race condition. Correlate count of requests exceeding the 10-attempt lockout against a single OTP session.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-110653
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.credential_access
  - attack.t1110
logsource:
  category: webserver
  product: linux
detection:
  selection:
    cs-method: 'POST'
    cs-uri-stem|contains:
      - 'admin-ajax.php'
    cs-uri-query|contains:
      - 'otp'
  condition: selection
falsepositives:
  - Users retrying mistyped OTPs (expect <5 attempts, not bursts of 50+)
  - API-driven legitimate integrations
level: medium

Deploy these with count-based correlation in your SIEM (e.g., count() by c-ip, otp_session_id > 20 within 60s) — the raw Sigma matches alone will under-specify the burst behavior. The signal is in the rate, not the individual request.

KQL — Microsoft Sentinel / Defender

This query assumes Apache/Nginx access logs are ingested via Syslog or CEF (CommonSecurityLog). It hunts for the burst pattern: more than 20 OTP verification POSTs from a single source IP within a 5-minute window — activity that should be physically impossible if the 10-attempt lockout were functioning.

KQL — Microsoft Sentinel / Defender
let threshold = 20;
let window = 5m;
let otpLogs = union isfuzzy=true
    (CommonSecurityLog
     | where RequestMethod == "POST"
     | where RequestURL has "admin-ajax.php"
       and (RequestURL has_any ("latepoint", "otp", "verify") or AdditionalExtensions has_any ("latepoint", "otp"))
     | project TimeGenerated, SourceIP, RequestURL, DeviceAction, SentBytes, ReceivedBytes),
    (Syslog
     | where SyslogMessage has_all ("POST", "admin-ajax.php")
       and SyslogMessage has_any ("latepoint", "otp", "verify")
     | extend SourceIP = extract(@'(\d{1,3}\.){3}\d{1,3}', 0, SyslogMessage)
     | project TimeGenerated, SourceIP, SyslogMessage));
otpLogs
| summarize RequestCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)
    by SourceIP, bin(TimeGenerated, window)
| where RequestCount > threshold
| extend BurstDurationSeconds = datetime_diff('second', LastSeen, FirstSeen)
| extend RequestsPerSecond = round(todouble(RequestCount) / iff(BurstDurationSeconds == 0, 1.0, todouble(BurstDurationSeconds)), 2)
| sort by RequestCount desc

Analysts should treat any hit with RequestsPerSecond > 1 against the OTP endpoint as near-certain malicious automation — no human submits an OTP faster than once per second, and legitimate resend flows are rate-limited by the plugin itself.

Velociraptor VQL

For on-host triage of a suspected compromised WordPress server, this artifact parses Apache/Nginx access logs for OTP verification bursts and identifies source IPs exceeding the theoretical lockout ceiling.

VQL — Velociraptor
-- Hunt LatePoint OTP verification burst activity in web server access logs (CVE-2026-110653)
LET log_lines = SELECT FullPath, Line
FROM foreach(
  row={
    SELECT FullPath
    FROM glob(globs=['/var/log/apache2/access*.log', '/var/log/nginx/access*.log', '/var/log/httpd/access_log*'])
  },
  query={
    SELECT FullPath, Line
    FROM parse_lines(filename=FullPath, accessor='file')
    WHERE Line =~ 'POST' AND Line =~ 'admin-ajax.php' AND Line =~ '(latepoint|otp|verify)'
  })

SELECT FullPath AS LogFile,
       count() AS OTPPostCount,
       parse_string_with_regex(string=Line, regex='(?P<srcip>(\d{1,3}\.){3}\d{1,3})').srcip[0] AS SourceIP,
       min(timestamp(epoch=0)) AS Placeholder
FROM log_lines
GROUP BY SourceIP
HAVING OTPPostCount > 15
ORDER BY OTPPostCount DESC

For a faster one-off pull on a live box, combine with parse_file targeting yesterday's log and correlate with netstat() output to confirm no lingering reverse shells — remember, if OTP bypass succeeded, the attacker's next move is typically account takeover, then credential harvesting or plugin/theme editor abuse for webshell deployment.

Post-Exploitation Triage Script (Bash)

If you find burst activity in logs, run this on the affected host to (a) verify plugin version exposure, (b) quantify the attack window, and (c) check for the most common post-OTP-bypass artifact — newly modified PHP files (webshells) in the WordPress tree.

Bash / Shell
#!/bin/bash
# CVE-2026-110653 triage - run on the WordPress host as root or the web user
WP_ROOT="/var/www/html"   # adjust to your docroot

# 1. Confirm installed LatePoint version
if command -v wp >/dev/null 2>&1; then
  wp --path="$WP_ROOT" plugin list --format=table | grep -i latepoint
else
  grep -m1 "Version:" "$WP_ROOT"/wp-content/plugins/latepoint*/latepoint.php 2>/dev/null
fi

# 2. Quantify OTP verification bursts (top offending IPs, last 7 days of logs)
for log in /var/log/apache2/access*.log* /var/log/nginx/access*.log*; do
  zgrep -h -E 'POST .*admin-ajax\.php' "$log" 2>/dev/null | grep -Ei 'latepoint|otp|verify'
done | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

# 3. Check for PHP files modified in the last 14 days (potential webshell drop after bypass)
find "$WP_ROOT" -name '*.php' -mtime -14 -type f 2>/dev/null | grep -Ev 'wp-content/(cache|uploads/[^ ]*\.(htaccess))' | head -50

# 4. Check WordPress users created recently (account takeover / rogue admin)
if command -v wp >/dev/null 2>&1; then
  wp --path="$WP_ROOT" user list --fields=ID,user_login,user_email,user_registered,roles --format=table | sort -k4 -r | head -10
fi

Remediation

  1. Update LatePoint immediately. Versions ≤ 5.7.4 are vulnerable. Upgrade to the first release after 5.7.4 published by the vendor via the WordPress plugin repository — verify the installed version with wp plugin list | grep latepoint and confirm the changelog references the OTP race-condition fix. If auto-updates are enabled for plugins, confirm the update actually landed; do not assume.
  2. If you cannot patch today, apply compensating controls:
    • Place a WAF or reverse-proxy rule rate-limiting POST /wp-admin/admin-ajax.php requests carrying LatePoint OTP parameters to 5 requests per minute per source IP (and ideally per session token). This closes the race window in practice, since exploitation depends on concurrency.
    • If OTP-based login is not business-critical this week, temporarily disable OTP verification or the customer-portal login flow in LatePoint settings.
  3. Database-level hardening for plugin developers in your supply chain: the correct fix pattern is an atomic conditional increment — UPDATE ... SET attempts = attempts + 1 WHERE session_id = ? AND attempts < 10 — checked via affected-row count, or a SELECT ... FOR UPDATE inside a transaction. If you run custom booking integrations against LatePoint's tables, audit them for the same pattern.
  4. Hunt retroactively. Pull 30 days of access logs through the KQL/VQL above. If bursts predate your patch date, assume OTP bypass occurred and pivot to account-level forensics: review bookings/customer accounts accessed, password resets, new admin users, and any outbound mail sent through the compromised session.
  5. Rotate and review. For any site where exploitation is suspected, force password resets on accounts that used OTP login, invalidate active sessions (wp user reset-password / session token table purge), and review WordPress administrator accounts for unauthorized additions.
  6. Longer term: enforce MFA at the WordPress admin layer independent of plugin-level OTP (e.g., via your IdP or a hardened MFA plugin), put the site behind a bot-management layer that can absorb request floods, and add plugin-version drift to your vulnerability management scanning cadence — WordPress plugin CVEs like this one are exactly where scheduled authenticated scanning pays for itself.

The Bottom Line

CVE-2026-110653 is a reminder that concurrency bugs in security controls are as dangerous as memory corruption — the lockout existed, was correctly designed on paper, and failed because of how it was implemented under parallel load. Defenders have a real advantage here: exploitation cannot be stealthy. Deploy the burst detections, patch past 5.7.4, and verify no one raced your OTP counter before you got there.

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.