Outdated Lodash Library Allows Application Logic Tampering
Your application uses a very old version of Lodash (3.10.1), a popular JavaScript utility library, that has a known security flaw. An attacker who can send crafted data to your application could manipulate how JavaScript objects behave globally — think of it like someone secretly changing the rules of the game for every player at once. Upgrading to the latest version of Lodash closes this gap immediately.
Business Impact And Actions
high urgencyBusiness Impact
If exploited, this flaw could allow an attacker to alter application behaviour in unexpected ways, potentially causing crashes, bypassing access controls, or corrupting data processing logic. This is a well-known, publicly documented vulnerability with a high EPSS exploitation probability score, meaning it is actively on attackers' radars. It may also flag as a finding in security audits or compliance reviews (e.g., SOC 2, ISO 27001), which could delay deals or renewals.
What To Do
- Ask your developer to upgrade the Lodash npm package to version 4.17.21 or later — this is typically a 30-minute task.
- Ask your developer to run a dependency audit (e.g., 'npm audit') after the upgrade to confirm no other outdated libraries are present.
- If an immediate upgrade is not possible, ask your developer to avoid passing any user-supplied data into Lodash's 'defaultsDeep' function as a short-term workaround.
- Schedule a recurring dependency review (monthly or quarterly) so outdated libraries are caught early in future.
Lodash 3.10.1 Prototype Pollution via defaultsDeep (CVE-2019-10744)
high severity CVSS 6.5–9.1Vulnerability Explanation
The lodash `defaultsDeep` function fails to properly validate constructor properties when recursively merging objects. An attacker can supply a crafted payload such as `{"constructor": {"prototype": {"isAdmin": true}}}` as input to `defaultsDeep`, which causes properties to be written directly onto `Object.prototype`. Because all JavaScript objects inherit from `Object.prototype`, this pollution affects every object in the runtime — potentially overriding security checks, corrupting application state, or causing denial of service via unexpected property collisions.
Root Cause
The `defaultsDeep` function in lodash < 4.17.12 does not guard against `__proto__` or `constructor.prototype` traversal during recursive object merging. This is a class-level design flaw in how the function handles deeply nested keys without sanitising reserved prototype-chain identifiers.
Technical Impact
An attacker who can control input passed to `defaultsDeep` (or related merge functions) can inject arbitrary properties onto `Object.prototype`, affecting all objects in the Node.js process. Practical outcomes include: bypassing boolean-based authorization checks (e.g., `isAdmin`), crashing the server through property conflicts, and in some chained scenarios, remote code execution. The CVSS 3.1 vector (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H) reflects high integrity and availability impact with no privileges or user interaction required.
Severity Justification
CVSS 3.1 base score of 9.1 (Critical) per some scorers; NVD/IBM score it at 6.5 (Medium) with vector AV:N/AC:L/PR:N/UI:N. The scanner-reported severity of High is a reasonable middle ground. Exploitability is realistic when user-controlled data reaches defaultsDeep — a common pattern. EPSS places this at the ~85th percentile of exploitation likelihood.
Affected Components
lodash < 4.17.12lodash-es < 4.17.14lodash-amd < 4.17.13lodash.defaultsdeep < 4.6.1
Remediation Steps
- Upgrade lodash to 4.17.21 or later (the latest stable patch release): `npm install lodash@^4.17.21` and commit the updated `package.json` and `package-lock.json`.
- If lodash is a transitive dependency (pulled in by another package), use npm's `overrides` field in `package.json` to force the safe version: `"overrides": { "lodash": "^4.17.21" }`.
- Run `npm audit` after upgrading to confirm the CVE is no longer reported.
- If an immediate upgrade is blocked, apply a short-term mitigation by freezing the prototype at application startup: `Object.freeze(Object.prototype)` — note this may break libraries that attempt to extend the prototype.
- Audit all call sites of `_.defaultsDeep`, `_.merge`, and `_.mergeWith` to ensure no user-controlled data is passed directly without sanitisation.
Verification Steps
- Run `npm list lodash` to confirm the installed version is 4.17.21 or later.
- Run `npm audit` and verify CVE-2019-10744 no longer appears in the output.
- If using a lockfile, inspect `package-lock.json` or `yarn.lock` to confirm no nested resolution of lodash < 4.17.12 remains.
- Run your existing test suite to confirm no regressions from the upgrade.
Code Examples (json)
// package.json — vulnerable
{
"dependencies": {
"lodash": "^3.10.1"
}
}
// package.json — fixed
{
"dependencies": {
"lodash": "^4.17.21"
}
}
// If lodash is a transitive dependency, force the safe version:
{
"overrides": {
"lodash": "^4.17.21"
}
}
Best Practices
- Never pass raw user-supplied JSON directly into deep merge functions — validate and sanitise input schemas first.
- Run `npm audit` as part of your CI/CD pipeline to catch newly disclosed vulnerabilities in dependencies automatically.
- Pin or constrain major dependency versions in `package.json` and review updates on a regular schedule.
- Consider using `Object.create(null)` for data-only objects that should not inherit from `Object.prototype`, breaking the prototype chain entirely.
Found this in your infrastructure?
VulWall scans for this and dozens of other issues automatically.
Scan Your Domain Free