CVE-2026-27128 Overview
A Time-of-Check-Time-of-Use (TOCTOU) race condition vulnerability exists in Craft CMS's token validation service affecting tokens that explicitly set a limited usage. The getTokenRoute() method reads a token's usage count, checks if it's within limits, then updates the database in separate non-atomic operations. By sending concurrent requests, an attacker can exploit this race condition to use a single-use impersonation token multiple times before the database update completes.
Critical Impact
Attackers with access to a valid user account impersonation URL can bypass single-use token restrictions through concurrent requests, potentially achieving privilege escalation if the token belongs to a higher-privileged account.
Affected Products
- Craft CMS versions 4.5.0-RC1 through 4.16.18
- Craft CMS versions 5.0.0-RC1 through 5.8.22
Discovery Timeline
- 2026-02-24 - CVE CVE-2026-27128 published to NVD
- 2026-02-24 - Last updated in NVD database
Technical Details for CVE-2026-27128
Vulnerability Analysis
The vulnerability resides in the getTokenRoute() method within Craft CMS's token validation service. The core issue is that token usage validation and increment operations are performed as separate, non-atomic database operations. When a request arrives, the system first queries the database to retrieve the token's current usageCount and usageLimit, evaluates whether the token has remaining uses, and then either increments the count or deletes the token in a subsequent database operation.
This sequence creates a classic TOCTOU race condition window. During the gap between checking the usage count and updating the database, multiple concurrent requests can each pass the validation check before any of them complete the database update. The result is that a token intended for single use can be consumed multiple times.
For successful exploitation, an attacker must obtain a valid, non-expired impersonation URL through some other means (such as interception, social engineering, or another vulnerability). Additionally, the attacker must bypass any rate-limiting protections that may be in place. The privilege escalation impact depends on the permissions of the account associated with the impersonation token.
Root Cause
The root cause is the lack of atomic operations in the token validation workflow (CWE-367: Time-of-Check Time-of-Use Race Condition). The original implementation performed a database query to check token validity, followed by a separate database update to modify the usage count. These non-atomic operations allowed a window where the token state could change between the check and the update, enabling multiple concurrent requests to exploit the same single-use token.
Attack Vector
The attack is network-based and requires the attacker to have already obtained a valid impersonation token URL. The exploitation technique involves:
- Acquiring a valid impersonation URL with an active, non-expired token
- Launching multiple concurrent HTTP requests to the impersonation endpoint
- Racing the requests to complete validation before the usage count is updated
- Successfully impersonating a user multiple times with a single-use token
The fix introduces a mutex lock mechanism using Craft::$app->getMutex() with a lock key based on the token value. This ensures that only one request can process a specific token at a time, eliminating the race condition window.
// Security patch implementing mutex lock - Source: GitHub Commit
{
// Take the opportunity to delete any expired tokens
$this->deleteExpiredTokens();
- $result = (new Query())
- ->select(['id', 'route', 'usageLimit', 'usageCount'])
- ->from([Table::TOKENS])
- ->where(['token' => $token])
- ->one();
-
- if (!$result) {
- // Remove it from the request so it doesn't get added to generated URLs
- Craft::$app->getRequest()->setToken(null);
+ $mutex = Craft::$app->getMutex();
+ $lockKey = "token:$token";
+ if (!$mutex->acquire($lockKey, 5)) {
return false;
}
- // Usage limit enforcement (for future requests)
- if ($result['usageLimit']) {
- // Does it have any more life after this?
- if ($result['usageCount'] < $result['usageLimit'] - 1) {
- // Increment its count
- $this->incrementTokenUsageCountById($result['id']);
- } else {
- // Just delete it
- $this->deleteTokenById($result['id']);
-
- // Remove it from the request as well so it doesn't get added to generated URLs
Source: GitHub Commit Details
Detection Methods for CVE-2026-27128
Indicators of Compromise
- Multiple rapid requests to impersonation URLs with the same token value within a short time window
- Anomalous user session activity where a single-use token appears to have been used multiple times
- Log entries showing concurrent authentication attempts with identical token parameters
- Unexpected privilege escalation events correlated with impersonation token usage
Detection Strategies
- Implement request logging that tracks token usage patterns and flags concurrent requests with the same token
- Monitor for rapid bursts of authentication requests targeting impersonation endpoints
- Correlate web application firewall logs with authentication events to identify race condition exploitation attempts
- Deploy application-level monitoring to detect token reuse anomalies
Monitoring Recommendations
- Enable detailed logging for the getTokenRoute() method and token validation operations
- Set up alerts for multiple concurrent requests to impersonation URLs from the same source
- Monitor database query patterns for tokens table access that may indicate exploitation attempts
- Review audit logs for impersonation events that exceed expected single-use behavior
How to Mitigate CVE-2026-27128
Immediate Actions Required
- Upgrade Craft CMS 4.x installations to version 4.16.19 or later
- Upgrade Craft CMS 5.x installations to version 5.8.23 or later
- Review impersonation token usage logs for any signs of exploitation
- Consider temporarily disabling user impersonation features until patching is complete
Patch Information
The vulnerability has been patched in Craft CMS versions 4.16.19 and 5.8.23. The fix introduces mutex-based locking to ensure atomic token validation operations. The security patch modifies src/services/Tokens.php to acquire a lock on the token before performing validation and update operations, preventing concurrent requests from exploiting the race condition. For additional details, refer to the GitHub Security Advisory GHSA-6fx5-5cw5-4897.
Workarounds
- Implement rate limiting at the web server or load balancer level to restrict concurrent requests to impersonation endpoints
- Configure application-level throttling to limit the frequency of token-based authentication attempts
- Review and restrict user impersonation permissions to minimize potential privilege escalation impact
- Deploy a Web Application Firewall (WAF) rule to detect and block rapid concurrent requests with identical token parameters
# Example nginx rate limiting configuration for impersonation endpoints
limit_req_zone $binary_remote_addr zone=impersonation_limit:10m rate=1r/s;
location /actions/users/impersonate {
limit_req zone=impersonation_limit burst=2 nodelay;
# Additional proxy or FastCGI configuration
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


