@@ -24,6 +24,13 @@ function escapeChar(match) {
2424 return '\\' + escapes [ match ] ;
2525}
2626
27+ // In order to prevent third-party code injection through
28+ // `_.templateSettings.variable`, we test it against the following regular
29+ // expression. It is intentionally a bit more liberal than just matching valid
30+ // identifiers, but still prevents possible loopholes through defaults or
31+ // destructuring assignment.
32+ var bareIdentifier = / ^ \s * ( \w | \$ ) + \s * $ / ;
33+
2734// JavaScript micro-templating, similar to John Resig's implementation.
2835// Underscore templating handles arbitrary delimiters, preserves whitespace,
2936// and correctly escapes quotes within interpolated code.
@@ -59,16 +66,25 @@ export default function template(text, settings, oldSettings) {
5966 } ) ;
6067 source += "';\n" ;
6168
62- // If a variable is not specified, place data values in local scope.
63- if ( ! settings . variable ) source = 'with(obj||{}){\n' + source + '}\n' ;
69+ var argument = settings . variable ;
70+ if ( argument ) {
71+ // Insure against third-party code injection.
72+ if ( ! bareIdentifier . test ( argument ) ) throw new Error (
73+ 'variable is not a bare identifier: ' + argument
74+ ) ;
75+ } else {
76+ // If a variable is not specified, place data values in local scope.
77+ source = 'with(obj||{}){\n' + source + '}\n' ;
78+ argument = 'obj' ;
79+ }
6480
6581 source = "var __t,__p='',__j=Array.prototype.join," +
6682 "print=function(){__p+=__j.call(arguments,'');};\n" +
6783 source + 'return __p;\n' ;
6884
6985 var render ;
7086 try {
71- render = new Function ( settings . variable || 'obj' , '_' , source ) ;
87+ render = new Function ( argument , '_' , source ) ;
7288 } catch ( e ) {
7389 e . source = source ;
7490 throw e ;
@@ -79,7 +95,6 @@ export default function template(text, settings, oldSettings) {
7995 } ;
8096
8197 // Provide the compiled source as a convenience for precompilation.
82- var argument = settings . variable || 'obj' ;
8398 template . source = 'function(' + argument + '){\n' + source + '}' ;
8499
85100 return template ;
0 commit comments