diff --git a/index.js b/index.js index 9ccc5d2496..dfe45bba96 100644 --- a/index.js +++ b/index.js @@ -10791,11 +10791,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. - var sourceURL = '//# sourceURL=' + - (hasOwnProperty.call(options, 'sourceURL') - ? (options.sourceURL + '').replace(/[\r\n]/g, ' ') + // 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(/\s/g, ' ') : ('lodash.templateSources[' + (++templateCounter) + ']') ) + '\n'; @@ -10828,8 +10828,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'; diff --git a/string/template.js b/string/template.js index 4e2dcc6cea..34f34d4277 100644 --- a/string/template.js +++ b/string/template.js @@ -152,9 +152,9 @@ function template(string, options, otherOptions) { // 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. - var sourceURL = hasOwnProperty.call(options, 'sourceURL') ? '//# sourceURL=' + (options.sourceURL + '').replace(/[\r\n]/g, ' ') + '\n' : ''; + // 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 = hasOwnProperty.call(options, 'sourceURL') ? '//# sourceURL=' + (options.sourceURL + '').replace(/\s/g, ' ') + '\n' : ''; string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) { interpolateValue || (interpolateValue = esTemplateValue); @@ -185,8 +185,6 @@ function template(string, options, otherOptions) { // 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';