Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sanitize sourceURL so it cannot affect evaled code #4518

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 3 additions & 5 deletions lodash.js
Expand Up @@ -14821,11 +14821,11 @@

// Use a sourceURL for easier debugging.
// The sourceURL gets injected into the source that's eval-ed, so be careful
// with lookup (in case of e.g. prototype pollution), and strip newlines if any.
// A newline wouldn't be a valid sourceURL anyway, and it'd enable code injection.
// to normalize all kinds of whitespace, so e.g. newlines (and unicode versions of it) can't sneak in
// and escape the comment, thus injecting code that gets evaled.
var sourceURL = '//# sourceURL=' +
(hasOwnProperty.call(options, 'sourceURL')
? (options.sourceURL + '').replace(/[\r\n]/g, ' ')
? (options.sourceURL + '').replace(/\s/g, ' ')
: ('lodash.templateSources[' + (++templateCounter) + ']')
) + '\n';

Expand Down Expand Up @@ -14858,8 +14858,6 @@

// If `variable` is not specified wrap a with-statement around the generated
// code to add the data object to the top of the scope chain.
// Like with sourceURL, we take care to not check the option's prototype,
// as this configuration is a code injection vector.
var variable = hasOwnProperty.call(options, 'variable') && options.variable;
if (!variable) {
source = 'with (obj) {\n' + source + '\n}\n';
Expand Down
12 changes: 12 additions & 0 deletions test/test.js
Expand Up @@ -22641,6 +22641,18 @@
assert.deepEqual(actual, expected);
});

QUnit.test('should not let a sourceURL inject code', function(assert) {
assert.expect(1);

var actual,
expected = 'no error';
try {
actual = _.template(expected, {'sourceURL': '\u2028\u2029\n!this would err if it was executed!'})();
} catch (e) {}

assert.equal(actual, expected);
});

QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
assert.expect(1);

Expand Down