Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-33877

CVE-2026-33877: ApostropheCMS Information Disclosure Flaw

CVE-2026-33877 is an information disclosure vulnerability in ApostropheCMS that enables unauthenticated username and email enumeration via timing side-channel attacks. This post covers technical details, affected versions, and mitigation.

Published:

CVE-2026-33877 Overview

ApostropheCMS, an open-source Node.js content management system, contains a timing side-channel vulnerability in the password reset endpoint (/api/v1/@apostrophecms/login/reset-request) that allows unauthenticated attackers to enumerate valid usernames and email addresses. The vulnerability exists in versions 4.28.0 and prior, where measurable response time differences can be exploited to distinguish between valid and invalid user accounts.

Critical Impact

This timing side-channel vulnerability enables automated enumeration of valid user accounts, which can be leveraged for credential stuffing attacks or targeted phishing campaigns against ApostropheCMS installations with password reset functionality enabled.

Affected Products

  • ApostropheCMS versions 4.28.0 and prior
  • Only instances with passwordReset option explicitly enabled (defaults to false)
  • Node.js deployments running vulnerable ApostropheCMS versions

Discovery Timeline

  • 2026-04-15 - CVE CVE-2026-33877 published to NVD
  • 2026-04-15 - Last updated in NVD database

Technical Details for CVE-2026-33877

Vulnerability Analysis

This vulnerability represents a classic timing side-channel attack (CWE-208) in the password reset flow. The core issue lies in the asymmetric timing behavior of the resetRequest handler. When a user is not found in the database, the handler returns after a fixed 2-second artificial delay. However, when a valid user is found, the system performs additional operations—including a MongoDB update and SMTP email transmission—without equivalent delay normalization, resulting in measurably different response times.

The endpoint accepts both username and email parameters via an $or MongoDB query, expanding the attack surface. Additionally, the existing checkLoginAttempts throttling mechanism only applies to the login flow, leaving the password reset endpoint without rate limiting protection.

Root Cause

The root cause is the inconsistent application of timing delays in the password reset flow. The original implementation introduced a fixed delay for error cases but failed to normalize response times when valid users are found and email operations are performed. This creates an observable timing oracle that leaks information about account validity.

Attack Vector

An unauthenticated attacker with network access can exploit this vulnerability by sending multiple password reset requests with different email addresses or usernames and measuring the response times. Valid accounts will exhibit different response timing patterns compared to invalid accounts. The lack of rate limiting on this endpoint enables automated high-volume enumeration attacks.

javascript
         },
         ...self.isPasswordResetEnabled() && {
           async resetRequest(req) {
-            const wait = (t = 2000) => Promise.delay(t);
+            const MIN_RESPONSE_TIME = 2000;
+            const startTime = Date.now();
             const site = (req.headers.host || '').replace(/:\d+$/, '');
             const email = self.apos.launder.string(req.body.email);
             if (!email.length) {
               throw self.apos.error('invalid', req.t('apostrophe:loginResetEmailRequired'));
             }
             let user;
-            // error not reported to browser for security reasons
             try {
               user = await self.getPasswordResetUser(req.body.email);
             } catch (e) {
               self.apos.util.error(e);
             }
             if (!user) {
-              await wait();
               self.apos.util.error(
                 `Reset password request error - the user ${email} doesn\`t exist.`
               );
-              return;
-            }
-            if (!user.email) {
-              await wait();
+            } else if (!user.email) {
               self.apos.util.error(
                 `Reset password request error - the user ${user.username} doesn\`t have an email.`

Source: GitHub Commit Update

Detection Methods for CVE-2026-33877

Indicators of Compromise

  • High volume of requests to /api/v1/@apostrophecms/login/reset-request endpoint from single IP addresses or IP ranges
  • Sequential or pattern-based email/username attempts in password reset requests
  • Unusual response time analysis patterns in web server logs indicating timing measurement activity
  • Burst traffic to password reset endpoints outside normal user behavior patterns

Detection Strategies

  • Implement web application firewall (WAF) rules to detect and alert on high-frequency password reset requests
  • Monitor for statistical anomalies in request rates to the password reset endpoint
  • Deploy log analysis to identify sequential enumeration patterns (alphabetical, dictionary-based, or leaked credential lists)
  • Enable application-level logging to track password reset request failures and success patterns

Monitoring Recommendations

  • Set up alerting thresholds for password reset request volumes exceeding baseline patterns
  • Correlate password reset enumeration attempts with subsequent authentication failures or successful logins
  • Monitor for requests from known malicious IP addresses or Tor exit nodes targeting the password reset endpoint
  • Track response time distributions for the password reset endpoint to detect ongoing exploitation attempts

How to Mitigate CVE-2026-33877

Immediate Actions Required

  • Upgrade ApostropheCMS to version 4.29.0 or later, which contains the security fix
  • If upgrade is not immediately possible, consider temporarily disabling the passwordReset option if not critical to operations
  • Implement rate limiting at the reverse proxy or WAF level for the /api/v1/@apostrophecms/login/reset-request endpoint
  • Review logs for signs of prior exploitation or enumeration attempts

Patch Information

The vulnerability has been fixed in ApostropheCMS version 4.29.0. The fix normalizes response times by tracking elapsed time and ensuring all responses take a minimum consistent duration, eliminating the timing oracle. The patch can be reviewed in the GitHub commit. Additional details are available in the GitHub Security Advisory GHSA-mj7r-x3h3-7rmr.

Workarounds

  • Disable the passwordReset option in ApostropheCMS configuration if the feature is not required
  • Implement network-level rate limiting on the password reset endpoint using reverse proxy or WAF
  • Add CAPTCHA or proof-of-work challenges to the password reset flow to slow automated enumeration
  • Deploy IP-based throttling rules to limit requests per IP address to the affected endpoint
bash
# Example nginx rate limiting configuration for password reset endpoint
limit_req_zone $binary_remote_addr zone=reset_limit:10m rate=5r/m;

location /api/v1/@apostrophecms/login/reset-request {
    limit_req zone=reset_limit burst=2 nodelay;
    limit_req_status 429;
    proxy_pass http://apostrophe_backend;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.