apidoc-core CVE-2025-13158 · CVE-2025-57317
Prototype Pollution in apidoc-core via doc-block path building.
The problem
apidoc-core <= 0.15.0 (all published versions) is affected by
CVE-2025-13158, CVE-2025-57317 (CWE-1321 Prototype Pollution). The published package has
no fix available — exactly what npm audit reports. When apidoc-core parses API documentation comments, group/element names flow into dotted object paths that `_createObjectPath` builds and `_pathToObject` resolves, after which the parsed values are merged in with `_.extend`. A crafted annotation whose path contains `__proto__` (or `constructor.prototype`) causes the merge to target `Object.prototype`, polluting every object in the process. This is reachable by anyone who can get the tool to parse an untrusted source file.
The fix — drop-in, no code changes
Add an overrides entry so every direct and transitive dependency on
apidoc-core resolves to the patched fork, then reinstall:
{
"overrides": {
"apidoc-core": "npm:@keep-lts/apidoc-core@^0.15.1"
}
}
Equivalent for Yarn: use resolutions. The public API is unchanged — nothing else to do.
✓ Live on npm: @keep-lts/apidoc-core · or install directly: npm i @keep-lts/apidoc-core
What we changed
`_createObjectPath` and `_pathToObject` now detect any path segment equal to `__proto__`, `constructor`, or `prototype` and return a fresh throwaway object instead of building into or resolving through the prototype chain. Legitimate nested paths (e.g. `local.parameter.fields`) and the `push`/`insert` attach methods are unaffected.
Proof of concept (the vulnerability)
// path segments derived from doc annotations reach the prototype:
const Parser = require('apidoc-core/lib/parser');
const root = {};
Parser.prototype._createObjectPath(root, 'group.__proto__.polluted', 'insert');
Object.assign(Parser.prototype._pathToObject('group.__proto__.polluted', root), { polluted: 'yes' });
console.log(({}).polluted); // => 'yes' on the unpatched version
@keep-lts/apidoc-core@0.15.1How we keep it trustworthy
- Minimal, surgical patch — security only, no feature changes.
- A regression test that fails on the original and passes on the patch; legitimate behaviour preserved.
- Published under the
@keep-ltsorg with the full advisory and tests inside the package; upstream license & attribution retained.
Full advisory and changelog ship inside the package (SECURITY.md, CHANGELOG.md).