CVE-2026-45013: Apostrophe Apostrophe Has A Weak Password Vulnerability
HIGHCVE-2026-45013 is a HIGH (CVSS 8.1) apostrophe has a weak password vulnerability (CWE-640: Weak Password Recovery Mechanism for Forgotten Password) affecting Apostrophe libraries in the npm ecosystem. The issue involves apostrophe has a weak password recovery mechanism for forgotten password and improper input validation. Remediation is available in the latest vendor maintenance releases.
CVE-2026-45013 at a Glance
Security Impact
CVSS: 8.1
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N).
How to Fix CVE-2026-45013
To remediate this vulnerability, upgrade all affected Apostrophe dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
npm install apostrophe@Latest secure release
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
npm ls apostrophe
How to Check if You Are Affected
To determine whether your Node.js application is affected by CVE-2026-45013, inspect your project dependencies using npm:
npm ls apostrophe
Analyze the terminal output to locate any version of Apostrophe in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than the patched release), your application is affected.
Note: The npm ls apostrophe command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-640: Weak Password Recovery Mechanism for Forgotten Password, where the product contains a mechanism for users to recover or change their passwords without knowing the original password, but the mechanism is weak. In Apostrophe, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-45013 Affected Apostrophe Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
apostrophe
|
npm |
≤ 4.29.0
|
|
References
Frequently Asked Questions
What is CVE-2026-45013?
Which Apostrophe versions are affected?
What version fixes CVE-2026-45013?
Is apostrophe affected?
What is the CVSS score of CVE-2026-45013?
What CWE is associated with CVE-2026-45013?
How can I check npm dependencies for CVE-2026-45013?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-gf43-24g3-5hw2",
"modified" : "2026-06-12T22:02:13Z",
"published" : "2026-05-14T18:27:12Z",
"aliases" : [ "CVE-2026-45013" ],
"summary" : "Apostrophe has a Weak Password Recovery Mechanism for Forgotten Password and Improper Input Validation",
"details" : "## Summary\n\nApostropheCMS's password reset flow constructs the reset URL using `req.hostname`, \nwhich is derived directly from the attacker-controlled HTTP `Host` header when \n`apos.baseUrl` is not explicitly configured. An unauthenticated attacker who knows \na victim's email address can send a crafted reset request that causes the application \nto email the victim a reset link pointing to the attacker's domain. When the victim \nclicks the link, the valid reset token is delivered to the attacker, enabling full \naccount takeover.\n\n## Affected Component\n\n`modules/@apostrophecms/login/index.js` — `resetRequest` route \nPrecondition: `passwordReset: true` is set **and** `apos.baseUrl` is not configured.\n\n## Vulnerability Details\n\nThe `setPrefixUrls` middleware (i18n layer) builds `req.baseUrl` using `req.hostname`:\n\n```js\n// Simplified from i18n middleware\nreq.baseUrl = `${req.protocol}://${req.hostname}`;\nreq.absoluteUrl = req.baseUrl + req.url;\n```\n\nThe `resetRequest` handler then passes this tainted value directly into URL construction:\n\n```js\nconst parsed = new URL(\n req.absoluteUrl, // ← tainted by attacker's Host header\n self.apos.baseUrl\n ? undefined\n : `${req.protocol}://${req.hostname}${port}` // ← also tainted\n);\nparsed.pathname = '/login';\nparsed.searchParams.append('reset', reset); // real, valid token\nparsed.searchParams.append('email', user.email);\nawait self.email(..., { url: parsed.toString() }, ...);\n// Email sent to victim with URL pointing to attacker-controlled domain\n```\n\nWhen `apos.baseUrl` is configured, it is used unconditionally and the attacker's \n`Host` header is ignored — that path is **not** vulnerable.\n\n## Attack Scenario\n\n1. Attacker identifies a valid user email (e.g. from the site's public interface).\n2. Attacker sends:\n```\n POST /api/v1/login/reset-request\n Host: evil.attacker.com\n Content-Type: application/json\n\n {\"email\": \"victim@example.com\"}\n```\n3. The application emails the victim:\n```\n Click here to reset your password:\n http://evil.attacker.com/login?reset=TOKEN&email=victim@example.com\n```\n4. Victim clicks the link; attacker's server captures `TOKEN`.\n5. Attacker calls the real target's reset endpoint with the captured token and \n sets a new password — full account takeover.\n\n## Preconditions\n\n- `passwordReset: true` configured in login module options (opt-in)\n- `apos.baseUrl` is **not** set (common in development and some production deployments)\n- Attacker knows or can enumerate a valid account email\n\n## Impact\n\nFull account takeover of any account whose email address is known to the attacker. \nNo authentication or interaction beyond sending a single HTTP request is required \nfrom the attacker. The victim need only click a link in a legitimate-looking \npassword reset email from their own site.\n\n## Remediation\n\n**Operators (immediate):** Always set `apos.baseUrl` in your configuration:\n\n```js\n// app.js or module configuration\nmodules: {\n '@apostrophecms/express': {\n options: {\n baseUrl: 'https://yourdomain.com'\n }\n }\n}\n```\n\n**Framework fix (recommended):** The `resetRequest` route should refuse to proceed \nif `apos.baseUrl` is not configured, rather than falling back to the tainted \n`req.hostname`. Example:\n\n```js\n// In resetRequest handler\nif (!self.apos.baseUrl) {\n throw self.apos.error(\n 'invalid',\n 'apos.baseUrl must be configured to enable password reset'\n );\n}\nconst parsed = new URL(self.loginUrl(), self.apos.baseUrl);\n```\n\nThis eliminates the attacker-controlled input entirely from the URL construction path.\n\n## References\n\n- [OWASP: Host Header Injection](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/17-Testing_for_Host_Header_Injection)\n- [CWE-640: Weak Password Recovery Mechanism for Forgotten Password](https://cwe.mitre.org/data/definitions/640.html)",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "npm",
"name" : "apostrophe"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"last_affected" : "4.29.0"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/apostrophecms/apostrophe/security/advisories/GHSA-gf43-24g3-5hw2"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-45013"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/apostrophecms/apostrophe"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-20", "CWE-640" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2026-05-14T18:27:12Z",
"nvd_published_at" : "2026-06-12T21:16:22Z"
}
}