Sanitize sourceURL so it cannot affect evaled code (#4518)

This commit is contained in:
Alex Brasetvik
2020-06-04 08:36:12 +02:00
committed by GitHub
parent 0cec225778
commit e7b28ea6cb
2 changed files with 15 additions and 5 deletions

View File

@@ -14821,11 +14821,11 @@
// Use a sourceURL for easier debugging. // Use a sourceURL for easier debugging.
// The sourceURL gets injected into the source that's eval-ed, so be careful // 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. // to normalize all kinds of whitespace, so e.g. newlines (and unicode versions of it) can't sneak in
// A newline wouldn't be a valid sourceURL anyway, and it'd enable code injection. // and escape the comment, thus injecting code that gets evaled.
var sourceURL = '//# sourceURL=' + var sourceURL = '//# sourceURL=' +
(hasOwnProperty.call(options, 'sourceURL') (hasOwnProperty.call(options, 'sourceURL')
? (options.sourceURL + '').replace(/[\r\n]/g, ' ') ? (options.sourceURL + '').replace(/\s/g, ' ')
: ('lodash.templateSources[' + (++templateCounter) + ']') : ('lodash.templateSources[' + (++templateCounter) + ']')
) + '\n'; ) + '\n';
@@ -14858,8 +14858,6 @@
// If `variable` is not specified wrap a with-statement around the generated // 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. // 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; var variable = hasOwnProperty.call(options, 'variable') && options.variable;
if (!variable) { if (!variable) {
source = 'with (obj) {\n' + source + '\n}\n'; source = 'with (obj) {\n' + source + '\n}\n';

View File

@@ -22641,6 +22641,18 @@
assert.deepEqual(actual, expected); 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) { QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
assert.expect(1); assert.expect(1);