Outdated JavaScript Utility Library Allows Application Behavior Tampering

Your application uses an old version of a popular JavaScript helper library called Lodash (version 3.10.1) that contains a known security flaw. An attacker who can send crafted data to your app could manipulate how it processes objects internally, potentially disrupting its behavior. Upgrading to the latest version of Lodash takes a developer under an hour and fully resolves the issue.

Business Impact And Actions

medium urgency

Business Impact

If exploited, this flaw could allow an attacker to alter how your application behaves at a fundamental level — causing unexpected errors, crashes, or in some cases bypassing application logic. While exploitation requires the attacker to be able to send data that your app processes through specific Lodash functions, the library is extremely widely used, making this a well-known and documented attack pattern. This may also flag as a finding in compliance audits (e.g., PCI-DSS, SOC 2) that require keeping third-party dependencies up to date.

What To Do

  1. Ask your developer to upgrade the Lodash npm package to version 4.17.21 (the latest stable release) — this is a straightforward dependency update, typically under an hour of work.
  2. After the upgrade, ask your developer to run your existing test suite to confirm nothing broke — Lodash 4.x is largely backward-compatible with 3.x for common usage.
  3. If you use automated dependency scanning tools (like Dependabot or Snyk), make sure they are enabled so future outdated libraries are flagged automatically.

Lodash < 4.17.5 Prototype Pollution via merge/defaultsDeep (CVE-2018-3721)

medium severity CVSS 5.3–6.5

Vulnerability Explanation

CVE-2018-3721 is a prototype pollution vulnerability in lodash versions prior to 4.17.5. The affected functions — `_.merge`, `_.mergeWith`, and `_.defaultsDeep` — fail to sanitize keys in source objects before recursively copying properties. When a source object contains a `__proto__` key (or a `constructor.prototype` path), the recursive merge logic traverses into `Object.prototype` itself and copies attacker-controlled properties onto it. Because all JavaScript objects inherit from `Object.prototype`, any property injected there becomes globally visible across the entire application, potentially overriding expected behavior, bypassing security checks, or causing denial of service via thrown exceptions.

Root Cause

The root cause is insufficient key validation in lodash's recursive merge implementation. The merge logic checks whether a property exists as an object on both source and target and recurses if so — but it does not block traversal into special prototype-chain properties like `__proto__`. This allows an attacker-controlled source object to redirect the merge into `Object.prototype`.

Technical Impact

An attacker who can control data passed to `_.merge`, `_.mergeWith`, or `_.defaultsDeep` can inject arbitrary properties onto `Object.prototype`. Depending on application logic, this can lead to: security check bypasses (e.g., overriding an `isAdmin` property that defaults to `false`), application crashes / denial of service via unexpected property types, or in chained scenarios, remote code execution if polluted properties influence code paths like template rendering or command construction.

Severity Justification

CVSS 3.0 base score of 5.3 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N) per IBM X-Force / NVD. Exploitation requires the attacker to control data that is passed to a specific set of lodash functions, which is a realistic but not universal condition. Impact is primarily integrity-related (property injection) rather than direct data exfiltration.

Affected Components

  • lodash < 4.17.5 (CVE-2018-3721 — __proto__ via merge/defaultsDeep)
  • lodash 4.17.5 – 4.17.10 (CVE-2018-16487 — incomplete fix, constructor.prototype bypass)

Remediation Steps

  1. Upgrade lodash to version 4.17.21 (latest stable) — this resolves CVE-2018-3721 and all subsequent prototype pollution CVEs in the 4.x line: `npm install lodash@4.17.21` or `yarn add lodash@4.17.21`.
  2. If lodash is a transitive dependency (pulled in by another package), use `npm ls lodash` to identify which packages depend on it, then update those packages or use an `overrides` / `resolutions` field in package.json to force the safe version.
  3. Run your test suite after upgrading. Lodash 4.x introduced breaking changes from 3.x (e.g., function signature changes in `_.assign`, `_.merge`). Review the lodash 3→4 migration guide if tests fail.
  4. Validate that any endpoints accepting JSON and passing it to `_.merge` / `_.defaultsDeep` sanitize or schema-validate input before processing.

Verification Steps

  1. Run `npm ls lodash` (or `yarn why lodash`) and confirm all resolved versions are 4.17.21.
  2. Run `npm audit` and verify CVE-2018-3721 no longer appears in the output.
  3. Optionally, run a quick proof-of-concept check in a dev environment: `const _ = require('lodash'); _.merge({}, JSON.parse('{"__proto__":{"polluted":true}}')); console.log({}.polluted);` — on the patched version this should print `undefined`.

Code Examples (bash)

Vulnerable
# package.json dependency pinned to vulnerable version
"lodash": "3.10.1"
Fixed
# Upgrade to latest safe version
npm install lodash@4.17.21

# Or, if lodash is a transitive dependency, force the version via overrides (npm 8.3+)
# In package.json:
# "overrides": {
#   "lodash": "4.17.21"
# }

Best Practices

  • Validate and schema-check all user-supplied JSON before passing it to object merge or deep-copy functions.
  • Consider using `Object.create(null)` for objects that serve as key-value stores, as these have no prototype chain to pollute.
  • Enable automated dependency scanning (e.g., GitHub Dependabot, Snyk, or `npm audit` in CI) to catch vulnerable transitive dependencies early.
  • Prefer `Map` over plain objects for dynamic key storage to avoid prototype chain exposure.

Found this in your infrastructure?

VulWall scans for this and dozens of other issues automatically.

Scan Your Domain Free