ES2015模板字符串安全问题

Mos*_*sho 11 javascript security ecmascript-6

以下是MDN的引用:

模板字符串不能由不受信任的用户构造,因为它们可以访问变量和函数.

一个例子:

`${console.warn("this is",this)}`; // "this is" Window

let a = 10;
console.warn(`${a+=20}`); // "30"
console.warn(a); // 30
Run Code Online (Sandbox Code Playgroud)

此处的示例未显示我可以看到的任何漏洞.

任何人都可以举一个利用这个漏洞利用的例子吗?

Ber*_*rgi 9

这毫无意义.模板字符串无权访问任何内容,也不会执行.模板字符串是该语言的语法元素.

动态构造模板字符串是没有问题的 - 它就像构建一个表达式(无论是什么格式,无论是代码字符串还是AST).MDN提示的问题是评估这样的表达式(例如,使用eval,将其序列化为提供给用户的脚本等) - 它可能包含任意代码,与字符串文字相反!但是你当然不会这样做,不是吗?

这个警告就像是说" 使用+运算符的连接不能由不受信任的用户构造,因为它们可以访问变量和函数. "并给出了示例"" + console.warn("this is",this) + "".嗯,对于语言的任何表达都是如此,所以它并不是特别有趣.


虽然我们讨论的是糟糕的编码,但当然有一种情况是使用模板字符串(嘿,它们是多行和诸如此类的)而不是字符串文字会导致问题:

function escapeString(str) {
    return JSON.stringify(str).slice(1, -1)
           .replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
}

// This is (kinda) fine!
var statement = 'var x = "Hello,\\n'+escapeString(userInput)+'";';
eval(statement); // some kind of evaluation

// But this is not:
var statement = 'var x = `Hello,\n'+escapeString(userInput)+'`;';
//                       ^                                   ^
Run Code Online (Sandbox Code Playgroud)

现在想象userInput包含一个${…}- 我们没有逃脱...

  • 这就像说"*使用`+`运算符的连接不能由不受信任的用户构造,因为它们可以访问变量和函数.*",例如`""+ console.warn("this is",this)+ ""` (3认同)