@@ -24,6 +24,13 @@ function escapeChar(match) {
24
24
return '\\' + escapes [ match ] ;
25
25
}
26
26
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
+
27
34
// JavaScript micro-templating, similar to John Resig's implementation.
28
35
// Underscore templating handles arbitrary delimiters, preserves whitespace,
29
36
// and correctly escapes quotes within interpolated code.
@@ -59,16 +66,25 @@ export default function template(text, settings, oldSettings) {
59
66
} ) ;
60
67
source += "';\n" ;
61
68
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
+ }
64
80
65
81
source = "var __t,__p='',__j=Array.prototype.join," +
66
82
"print=function(){__p+=__j.call(arguments,'');};\n" +
67
83
source + 'return __p;\n' ;
68
84
69
85
var render ;
70
86
try {
71
- render = new Function ( settings . variable || 'obj' , '_' , source ) ;
87
+ render = new Function ( argument , '_' , source ) ;
72
88
} catch ( e ) {
73
89
e . source = source ;
74
90
throw e ;
@@ -79,7 +95,6 @@ export default function template(text, settings, oldSettings) {
79
95
} ;
80
96
81
97
// Provide the compiled source as a convenience for precompilation.
82
- var argument = settings . variable || 'obj' ;
83
98
template . source = 'function(' + argument + '){\n' + source + '}' ;
84
99
85
100
return template ;
0 commit comments