Wysoka

Apostrophe has a Weak Password Recovery Mechanism for Forgotten Password and Improper Input Validation

  • Ujawniono: 14.05.2026
  • Aktualizacja: 11.10.2026 10:22

Summary

ApostropheCMS's password reset flow constructs the reset URL using req.hostname, which is derived directly from the attacker-controlled HTTP Host header when apos.baseUrl is not explicitly configured. An unauthenticated attacker who knows a victim's email address can send a crafted reset request that causes the application to email the victim a reset link pointing to the attacker's domain. When the victim clicks the link, the valid reset token is delivered to the attacker, enabling full account takeover.

Affected Component

modules/@apostrophecms/login/index.js — resetRequest route
Precondition: passwordReset: true is set and apos.baseUrl is not configured.

Vulnerability Details

The setPrefixUrls middleware (i18n layer) builds req.baseUrl using req.hostname:

js
// Simplified from i18n middleware
req.baseUrl = `${req.protocol}://${req.hostname}`;
req.absoluteUrl = req.baseUrl + req.url;

The resetRequest handler then passes this tainted value directly into URL construction:

js
const parsed = new URL(
  req.absoluteUrl,           // ← tainted by attacker's Host header
  self.apos.baseUrl
    ? undefined
    : `${req.protocol}://${req.hostname}${port}`  // ← also tainted
);
parsed.pathname = '/login';
parsed.searchParams.append('reset', reset);   // real, valid token
parsed.searchParams.append('email', user.email);
await self.email(..., { url: parsed.toString() }, ...);
// Email sent to victim with URL pointing to attacker-controlled domain

When apos.baseUrl is configured, it is used unconditionally and the attacker's Host header is ignored — that path is not vulnerable.

Attack Scenario

  1. Attacker identifies a valid user email (e.g. from the site's public interface).
  2. Attacker sends:
   POST /api/v1/login/reset-request
   Host: evil.attacker.com
   Content-Type: application/json

   {"email": "victim@example.com"}
  1. The application emails the victim:
   Click here to reset your password:
   http://evil.attacker.com/login?reset=TOKEN&email=victim@example.com
  1. Victim clicks the link; attacker's server captures TOKEN.
  2. Attacker calls the real target's reset endpoint with the captured token and sets a new password — full account takeover.

Preconditions

  • passwordReset: true configured in login module options (opt-in)
  • apos.baseUrl is not set (common in development and some production deployments)
  • Attacker knows or can enumerate a valid account email

Impact

Full account takeover of any account whose email address is known to the attacker. No authentication or interaction beyond sending a single HTTP request is required from the attacker. The victim need only click a link in a legitimate-looking password reset email from their own site.

Remediation

Operators (immediate): Always set apos.baseUrl in your configuration:

js
// app.js or module configuration
modules: {
  '@apostrophecms/express': {
    options: {
      baseUrl: 'https://yourdomain.com'
    }
  }
}

Framework fix (recommended): The resetRequest route should refuse to proceed if apos.baseUrl is not configured, rather than falling back to the tainted req.hostname. Example:

js
// In resetRequest handler
if (!self.apos.baseUrl) {
  throw self.apos.error(
    'invalid',
    'apos.baseUrl must be configured to enable password reset'
  );
}
const parsed = new URL(self.loginUrl(), self.apos.baseUrl);

This eliminates the attacker-controlled input entirely from the URL construction path.

References

Czego dotyczy

Kliknij technologię, aby zobaczyć wszystkie dotyczące jej podatności.

PlatformaPaczkaPodatne wersjePoprawka w wersji
Paczka npm apostrophe <= 4.29.0 brak poprawki

Odnośniki

Ocena CVSS 8.1/10
Wektor CVSS
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
Słabość (CWE)
CWE-20, CWE-640
Platforma
npm
Paczka
apostrophe
Ujawniono
14.05.2026
Aktualizacja
11.10.2026 10:22

Źródła i licencje

OSV / GitHub Advisory Database - GHSA-gf43-24g3-5hw2 - 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ć.

Wszystkie (27) w archiwum
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

  1. 2020: 2
  2. 2021: 2
  3. 2022: 0
  4. 2023: 0
  5. 2024: 0
  6. 2025: 0
  7. 2026: 23
Istotność:
  1. Wysoka · 7.3 CVE-2026-45011 = 4.29.0 brak poprawki
  2. Apostrophe has a Weak Password Recovery Mechanism for Forgotten Password and Improper Input Validation ten wpis
    Wysoka · 8.1 CVE-2026-45013 <= 4.29.0 brak poprawki
  3. Krytyczna · 9.8 CVE-2021-25979 >= 2.63.0, < 3.4.0 3.4.0

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.

Podłącz swoją aplikację
Newsletter DockRay

Bezpieczeństwo aplikacji w Twojej skrzynce

Najważniejsze podatności, konkretne zalecenia i praktyczne wskazówki dla Twoich aplikacji. Wybierz technologie i śledź to, co ma znaczenie dla Twojego projektu.

  • Codzienne zestawienie nowych podatności, także krytycznych.
  • Powiadomienia o ważnych aktualizacjach.
  • Praktyczne porady o bezpieczeństwie i monitoringu aplikacji.

Pozostaw puste, aby otrzymywać informacje o wszystkich technologiach.

Zapis jest bezpłatny. Wypiszesz się jednym kliknięciem w wiadomości.