CVE-2026-26185 Overview
CVE-2026-26185 is a timing-based user enumeration vulnerability discovered in Directus, a real-time API and App dashboard for managing SQL database content. Before version 11.14.1, the password reset functionality exhibits a timing side-channel that allows attackers to determine whether a given email address is registered in the system. When an invalid reset_url parameter is provided, the response time differs by approximately 500ms between existing and non-existing users, enabling reliable user enumeration attacks.
Critical Impact
Attackers can enumerate valid user accounts through the password reset endpoint, potentially facilitating targeted phishing campaigns, credential stuffing attacks, or brute-force authentication attempts against confirmed accounts.
Affected Products
- Directus versions prior to 11.14.1
- Directus API password reset functionality
- Self-hosted Directus installations with exposed password reset endpoints
Discovery Timeline
- 2026-02-12 - CVE CVE-2026-26185 published to NVD
- 2026-02-12 - Last updated in NVD database
Technical Details for CVE-2026-26185
Vulnerability Analysis
This vulnerability falls under CWE-203 (Observable Discrepancy), commonly known as a timing attack or side-channel vulnerability. The root issue lies in the order of operations within the password reset flow in Directus. The application performs URL validation and user lookup in a sequence that creates a measurable timing difference depending on whether a user exists in the database.
When a password reset request is submitted with an invalid reset_url parameter, the system's response timing reveals information about user existence. If the user exists, additional processing occurs (including the 500ms stall time implementation) before the error is thrown, whereas non-existent users trigger an earlier exit path. This timing differential of approximately 500ms is significant enough to be reliably measured over network requests.
Root Cause
The vulnerability originates from the placement of the URL validation check relative to the user lookup operation. In the vulnerable code path, the application first retrieves the user by email address, then validates whether the provided URL is in the allowed list. This ordering means that the stall time mechanism (designed to prevent timing attacks) is applied inconsistently—only executing after a user is found, not before the URL validation error is thrown.
Attack Vector
An attacker can exploit this vulnerability remotely without authentication by sending password reset requests with a deliberately invalid reset_url parameter paired with target email addresses. By measuring response times across multiple requests, the attacker can reliably determine which email addresses correspond to registered users. This network-based attack requires no privileges or user interaction.
// Security patch from api/src/services/users.ts
// Source: https://github.com/directus/directus/commit/e69aa7a5248c6e3e822cb1ac354dee295df90b2a
const STALL_TIME = 500;
const timeStart = performance.now();
+ if (url && isUrlAllowed(url, env['PASSWORD_RESET_URL_ALLOW_LIST'] as string) === false) {
+ throw new InvalidPayloadError({ reason: `URL "${url}" can't be used to reset passwords` });
+ }
+
const user = await this.getUserByEmail(email);
if (user?.status !== 'active') {
await stall(STALL_TIME, timeStart);
throw new ForbiddenError();
}
- if (url && isUrlAllowed(url, env['PASSWORD_RESET_URL_ALLOW_LIST'] as string) === false) {
- throw new InvalidPayloadError({ reason: `URL "${url}" can't be used to reset passwords` });
- }
-
const mailService = new MailService({
schema: this.schema,
knex: this.knex,
The fix moves the URL validation check to occur before the user lookup, ensuring that invalid URL requests are rejected immediately with consistent timing regardless of whether the user exists.
Detection Methods for CVE-2026-26185
Indicators of Compromise
- Unusually high volume of password reset requests from single IP addresses or IP ranges
- Sequential password reset attempts targeting different email addresses in rapid succession
- Password reset requests containing obviously invalid reset_url parameters
- Correlation between enumeration activity and subsequent authentication attempts against discovered accounts
Detection Strategies
- Implement rate limiting on the password reset endpoint and alert on threshold breaches
- Monitor for patterns of password reset requests that use the same invalid URL across multiple email addresses
- Deploy anomaly detection to identify automated enumeration behavior based on request timing patterns
- Review web application firewall (WAF) logs for suspicious POST requests to /auth/password/request endpoints
Monitoring Recommendations
- Enable detailed logging for all password reset requests including source IP, timestamp, and provided parameters
- Set up alerts for password reset request rates exceeding normal baseline thresholds
- Monitor response time metrics on authentication-related endpoints to detect potential timing attack reconnaissance
- Correlate password reset activity with subsequent login attempts to identify potential attack chains
How to Mitigate CVE-2026-26185
Immediate Actions Required
- Upgrade Directus to version 11.14.1 or later immediately
- Review access logs for evidence of exploitation attempts against the password reset endpoint
- Implement or strengthen rate limiting on authentication-related API endpoints
- Consider temporarily restricting access to password reset functionality from untrusted networks if immediate patching is not possible
Patch Information
The vulnerability is fixed in Directus version 11.14.1. The patch reorders the URL validation logic to execute before the user lookup, ensuring consistent response timing regardless of user existence. Organizations should upgrade to version 11.14.1 or later to remediate this vulnerability.
For detailed patch information, refer to:
Workarounds
- Implement a web application firewall (WAF) rule to rate limit requests to the password reset endpoint
- Deploy a reverse proxy with consistent response time delays for all authentication-related endpoints
- Restrict password reset functionality to internal networks or VPN-only access until patching is complete
- Enable CAPTCHA or similar challenge-response mechanisms on the password reset form to impede automated enumeration
# Example: Nginx rate limiting configuration for password reset endpoint
limit_req_zone $binary_remote_addr zone=password_reset:10m rate=5r/m;
location /auth/password/request {
limit_req zone=password_reset burst=2 nodelay;
limit_req_status 429;
proxy_pass http://directus_backend;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

