SIGN IN SIGN UP

A modern JavaScript utility library delivering modularity, performance, & extras.

0 0 1 JavaScript

[Security Critical] _.template() uses new Function() — arbitrary code execution risk #1

open bhaktateas opened this issue · 0 comments
bhaktateas bhaktateas commented

Summary

_.template() in lodash.js and dist/lodash.js compiles user-supplied template strings into executable JavaScript using the Function constructor (dynamic code evaluation equivalent to eval). If an attacker can influence the template string or options.variable, this leads to Remote Code Execution (RCE).

Affected Files

File Lines
lodash.js 14894–15009
dist/lodash.js (identical copy)

Evidence

// lodash.js ~line 14994
var result = attempt(function() {
  return Function(importsKeys, sourceURL + 'return ' + source)
    .apply(undefined, importsValues);
});

The source variable is built by concatenating user-controlled evaluateValue blocks (from <% ... %> delimiters) directly into a function body string passed to new Function(...). While the variable option now validates against reForbiddenIdentifierChars, the evaluate delimiter <% code %> still injects raw JS.

Impact

Any consumer of _.template() that passes untrusted input as the template string is vulnerable to arbitrary code execution (CVE-2021-23337 class of issue).

Recommendation

  1. Never pass untrusted input as the template string argument to _.template() — enforce this in code review.
  2. Prefer _.escape() + string interpolation, or a sandboxed templating engine.
  3. Add a lint rule / SAST policy to flag _.template( calls that accept dynamic/user-controlled strings.
  4. If server-side rendering is involved, consider disabling the evaluate delimiter: _.templateSettings.evaluate = /($^)/;

References

ADD COMMENT