CVE-2026-32730
ApostropheCMS MFA/TOTP Bypass via Incorrect MongoDB Query in Bearer Token Middleware
ApostropheCMS is an open-source content management framework. Prior to version 4.28.0, the bearer token authentication middleware in @apostrophecms/express/index.js (lines 386-389) contains an incorrect MongoDB query that allows incomplete login tokens — where the password was verified but TOTP/MFA requirements were NOT — to be used as fully authenticated bearer tokens. This completely bypasses multi-factor authentication for any ApostropheCMS deployment using @apostrophecms/login-totp or any custom afterPasswordVerified login requirement. Version 4.28.0 fixes the issue.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.1
ApostropheCMS MFA/TOTP Bypass via Incorrect MongoDB Query in Bearer Token Middleware
ApostropheCMS is an open-source content management framework. Prior to version 4.28.0, the bearer token authentication middleware in @apostrophecms/express/index.js (lines 386-389) contains an incorrect MongoDB query that allows incomplete login tokens — where the password was verified but TOTP/MFA requirements were NOT — to be used as fully authenticated bearer tokens. This completely bypasses multi-factor authentication for any ApostropheCMS deployment using @apostrophecms/login-totp or any custom afterPasswordVerified login requirement. Version 4.28.0 fixes the issue.
- Record
CVE-2026-32730- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-287, CWE-305
- Updated
- 2026-11-02
EUVDEUVD-2026-12975
8.1
ApostropheCMS is an open-source content management framework. Prior to version 4.28.0, the bearer token authentication middleware in @apostrophecms/express/index.js (lines 386-389) contains an incorrect MongoDB query that allows incomplete login tokens — where the password was verified but TOTP/MFA requirements were NOT — to be used as fully authenticated bearer tokens. This completely bypasses multi-factor authentication for any ApostropheCMS deployment using @apostrophecms/login-totp or any custom afterPasswordVerified login requirement. Version 4.28.0 fixes the issue.
- Record
EUVD-2026-12975- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-v9xm-ffx2-7h35
8.1
ApostropheCMS MFA/TOTP Bypass via Incorrect MongoDB Query in Bearer Token Middleware
MFA/TOTP Bypass via Incorrect MongoDB Query in Bearer Token Middleware
Summary
The bearer token authentication middleware in @apostrophecms/express/index.js (lines 386-389) contains an incorrect MongoDB query that allows incomplete login tokens — where the password was verified but TOTP/MFA requirements were NOT — to be used as fully authenticated bearer tokens. This completely bypasses multi-factor authentication for any ApostropheCMS deployment using @apostrophecms/login-totp or any custom afterPasswordVerified login requirement.
Severity
The AC is High because the attacker must first obtain the victim's password. However, the entire purpose of MFA is to protect accounts when passwords are compromised (credential stuffing, phishing, database breaches), so this bypass negates the security control entirely.
Affected Versions
All versions of ApostropheCMS from 3.0.0 to 4.27.1, when used with @apostrophecms/login-totp or any custom afterPasswordVerified requirement.
Root Cause
In packages/apostrophe/modules/@apostrophecms/express/index.js, the getBearer() function (line 377) queries MongoDB for valid bearer tokens. The query at lines 386-389 is intended to only match tokens where the requirementsToVerify array is either absent (no MFA configured) or empty (all MFA requirements completed):
async function getBearer() {
const bearer = await self.apos.login.bearerTokens.findOne({
_id: req.token,
expires: { $gte: new Date() },
// requirementsToVerify array should be empty or inexistant
// for the token to be usable to log in.
$or: [
{ requirementsToVerify: { $exists: false } },
{ requirementsToVerify: { $ne: [] } } // BUG
]
});
return bearer && bearer.userId;
}
The comment correctly states the intent: the array should be "empty or inexistant." However, the MongoDB operator $ne: [] matches documents where requirementsToVerify is NOT an empty array — meaning it matches tokens that still have unverified requirements. This is the exact opposite of the intended behavior.
| Token State | requirementsToVerify | $ne: [] result | Should match? |
|---|---|---|---|
| No MFA configured | (field absent) | N/A ($exists: false matches) | Yes |
| TOTP pending | ["AposTotp"] | true (BUG!) | No |
| All verified | [] | false (BUG!) | Yes |
| Field removed ($unset) | (field absent) | N/A ($exists: false matches) | Yes |
Attack Scenario
Prerequisites
- ApostropheCMS instance with
@apostrophecms/login-totpenabled - Attacker knows the victim's username and password (e.g., from credential stuffing, phishing, or a database breach)
- Attacker does NOT know the victim's TOTP secret/code
Steps
-
Authenticate with password only:
POST /api/v1/@apostrophecms/login/login Content-Type: application/json {"username": "admin", "password": "correct_password", "session": false} -
Receive incomplete token (server correctly requires TOTP):
{"incompleteToken": "clxxxxxxxxxxxxxxxxxxxxxxxxx"} -
Use incomplete token as bearer token (bypassing TOTP):
GET /api/v1/@apostrophecms/page Authorization: Bearer clxxxxxxxxxxxxxxxxxxxxxxxxx -
Full authenticated access granted. The bearer token middleware matches the token because
requirementsToVerify: ["AposTotp"]satisfies$ne: []. The attacker has complete API access as the victim without ever providing a TOTP code.
Proof of Concept
See mfa-bypass-poc.js — demonstrates the query logic bug with all token states. Run:
#!/usr/bin/env node
/**
* PoC: MFA/TOTP Bypass via Incorrect MongoDB Query in Bearer Token Middleware
*
* ApostropheCMS's bearer token middleware in @apostrophecms/express/index.js
* has a logic error in the MongoDB query that validates bearer tokens.
*
* The comment says:
* "requirementsToVerify…
- Record
GHSA-v9xm-ffx2-7h35- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-287, CWE-305
- Updated
- 2026-11-02
NVD
8.1
ApostropheCMS is an open-source content management framework. Prior to version 4.28.0, the bearer token authentication middleware in @apostrophecms/express/index.js (lines 386-389) contains an incorrect MongoDB query that allows incomplete login tokens — where the password was verified but TOTP/MFA requirements were NOT — to be used as fully authenticated bearer tokens. This completely bypasses multi-factor authentication for any ApostropheCMS deployment using @apostrophecms/login-totp or any custom afterPasswordVerified login requirement. Version 4.28.0 fixes the issue.
- Record
CVE-2026-32730- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-287, CWE-305
- Updated
- 2026-11-02
OSV
8.1
ApostropheCMS MFA/TOTP Bypass via Incorrect MongoDB Query in Bearer Token Middleware
ApostropheCMS is an open-source content management framework. Prior to version 4.28.0, the bearer token authentication middleware in @apostrophecms/express/index.js (lines 386-389) contains an incorrect MongoDB query that allows incomplete login tokens — where the password was verified but TOTP/MFA requirements were NOT — to be used as fully authenticated bearer tokens. This completely bypasses multi-factor authentication for any ApostropheCMS deployment using @apostrophecms/login-totp or any custom afterPasswordVerified login requirement. Version 4.28.0 fixes the issue.
- Record
CVE-2026-32730- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-287, CWE-305
- Updated
- 2026-11-02
OSVGHSA-v9xm-ffx2-7h35
8.1
ApostropheCMS MFA/TOTP Bypass via Incorrect MongoDB Query in Bearer Token Middleware
MFA/TOTP Bypass via Incorrect MongoDB Query in Bearer Token Middleware
Summary
The bearer token authentication middleware in @apostrophecms/express/index.js (lines 386-389) contains an incorrect MongoDB query that allows incomplete login tokens — where the password was verified but TOTP/MFA requirements were NOT — to be used as fully authenticated bearer tokens. This completely bypasses multi-factor authentication for any ApostropheCMS deployment using @apostrophecms/login-totp or any custom afterPasswordVerified login requirement.
Severity
The AC is High because the attacker must first obtain the victim's password. However, the entire purpose of MFA is to protect accounts when passwords are compromised (credential stuffing, phishing, database breaches), so this bypass negates the security control entirely.
Affected Versions
All versions of ApostropheCMS from 3.0.0 to 4.27.1, when used with @apostrophecms/login-totp or any custom afterPasswordVerified requirement.
Root Cause
In packages/apostrophe/modules/@apostrophecms/express/index.js, the getBearer() function (line 377) queries MongoDB for valid bearer tokens. The query at lines 386-389 is intended to only match tokens where the requirementsToVerify array is either absent (no MFA configured) or empty (all MFA requirements completed):
async function getBearer() {
const bearer = await self.apos.login.bearerTokens.findOne({
_id: req.token,
expires: { $gte: new Date() },
// requirementsToVerify array should be empty or inexistant
// for the token to be usable to log in.
$or: [
{ requirementsToVerify: { $exists: false } },
{ requirementsToVerify: { $ne: [] } } // BUG
]
});
return bearer && bearer.userId;
}
The comment correctly states the intent: the array should be "empty or inexistant." However, the MongoDB operator $ne: [] matches documents where requirementsToVerify is NOT an empty array — meaning it matches tokens that still have unverified requirements. This is the exact opposite of the intended behavior.
| Token State | requirementsToVerify | $ne: [] result | Should match? |
|---|---|---|---|
| No MFA configured | (field absent) | N/A ($exists: false matches) | Yes |
| TOTP pending | ["AposTotp"] | true (BUG!) | No |
| All verified | [] | false (BUG!) | Yes |
| Field removed ($unset) | (field absent) | N/A ($exists: false matches) | Yes |
Attack Scenario
Prerequisites
- ApostropheCMS instance with
@apostrophecms/login-totpenabled - Attacker knows the victim's username and password (e.g., from credential stuffing, phishing, or a database breach)
- Attacker does NOT know the victim's TOTP secret/code
Steps
-
Authenticate with password only:
POST /api/v1/@apostrophecms/login/login Content-Type: application/json {"username": "admin", "password": "correct_password", "session": false} -
Receive incomplete token (server correctly requires TOTP):
{"incompleteToken": "clxxxxxxxxxxxxxxxxxxxxxxxxx"} -
Use incomplete token as bearer token (bypassing TOTP):
GET /api/v1/@apostrophecms/page Authorization: Bearer clxxxxxxxxxxxxxxxxxxxxxxxxx -
Full authenticated access granted. The bearer token middleware matches the token because
requirementsToVerify: ["AposTotp"]satisfies$ne: []. The attacker has complete API access as the victim without ever providing a TOTP code.
Proof of Concept
See mfa-bypass-poc.js — demonstrates the query logic bug with all token states. Run:
#!/usr/bin/env node
/**
* PoC: MFA/TOTP Bypass via Incorrect MongoDB Query in Bearer Token Middleware
*
* ApostropheCMS's bearer token middleware in @apostrophecms/express/index.js
* has a logic error in the MongoDB query that validates bearer tokens.
*
* The comment says:
* "requirementsToVerify…
- Record
GHSA-v9xm-ffx2-7h35- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-287, CWE-305
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
apostrophenpm |
through 4.27.1 | 4.28.0 |
apostrophenpm |
before 4.28.0 | 4.28.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-32730 is a high vulnerability (CVSS 8.1) in Apostrophecms Apostrophe, published March 18, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.38%, the 32nd percentile. Fixed in apostrophe 4.28.0.
References
Left out here: the rest of 2 source descriptions. The JSON record has them.