Eval是邪恶的…那我应该用什么来代替呢?
ajax请求返回一个标准的JSON数组,填充我的用户input。 input已被消毒,并使用eval()函数,我可以很容易地创build我的JavaScript对象,并更新我的网页…
所以这是问题。 无论我如何努力消毒input,我宁愿不使用eval()函数。 我已经检查谷歌的方式来使用“没有eval的AJAX的JSON”,并跑了一堆不同的方法…
我应该使用哪一个? 有没有一个标准的,可靠的方法来做到这一点?
json.org有一个很好的JavaScript库
简单的用法:
JSON.parse('[{"some":"json"}]'); JSON.stringify([{some:'json'}]);
编辑 :正如在评论中指出,这使用eval,如果你通过它的来源(虽然它看起来是消毒第一)
为了完全避免它,看看json_parse或者json-sans-eval
json2.js是不安全的,json_parse.js是慢的,json-sans-eval.js是不validation的
有没有一个标准的,可靠的方式来做到这一点?
在即将到来的ECMAScript 3.1版本的JavaScript中有一个build议的标准方法: JSON.parse 。
它将在IE8,Firefox 3.1 / 3.5以及未来其他stream行的浏览器中得到支持。 与此同时,您可以退回到eval(),也可以使用eval()。 邪恶可能会或可能不会; 肯定会比JSON.parse慢。 但是这是通常的parsingJSON的方法。
如果攻击者能够通过JSON向内容注入恶意的JavaScript,那么您就有更多的问题需要担心,而不是eval-is-evil。
我想说,一旦input信息被消毒,eval就是最好的select。 如果你的服务器遭到入侵,人们将能够发送他们想要的任何脚本给客户端。 因此,评估并不是一个很大的安全风险。 如果您担心人们在到达客户端之前操纵数据包,那么脚本本身可以被修改。
不要担心评估。 但是请确保将其包装在try … catch块中,以便您的用户在JSON受到损坏时不会收到JS错误。
🙂
为了安全地将JSON转换为JS对象,您应该使用JSONparsing器,例如该库提供的JSON.parse()函数。
比较命令devise模式: http : //en.wikipedia.org/wiki/Command_pattern 。 鉴于此,您可以精确地定义客户端可以执行的操作,并且您的应用程序将与底层解释一样安全。
取决于你想用卫生完成什么。 我在原型框架支持JSON和安全评估方面取得了巨大的成功。
如果您确定没有注入风险,并且您没有eval()ing
循环,则使用eval()
。 它会比较有利的其他选项,肯定会更慢,可能会打破,并要求客户下载额外的代码。
从jQuery“被盗”
// Try to use the native JSON parser first return window.JSON && window.JSON.parse ? window.JSON.parse( data ) : (new Function("return " + data))();
问题: eval构成的问题是它在全局范围内执行
eval.call(document, "console.log(this)") eval.call(navigator, "console.log(this)") eval.call(window, "console.log(this)") (function(){eval.call(document, "console.log(this)")})() >Window
场景:
假定您在各种文档元素的标记代码中使用各个属性,例如不可见的属性
<img src="" onvisible="src='http://www.example.com/myimg.png';">
你想获得所有具有这个属性的元素,把onvisible-content-string变成一个闭包,并把它放到一个EventHandler队列中。 这是JS函数构造函数进入的地方。
Function === 0..constructor.constructor >true Function('return [this, arguments]').call(window, 1,2,3) >Window, Arguments[3]] Function('return [this, arguments]').call(document, 1,2,3) >Document, Arguments[3]] Function('return [this, arguments]').call(navigator, 1,2,3) >Navigator, Arguments[3]]
把它放在一起:
var eventQueue = []; var els = document.querySelectorAll('[onvisible]'); for (var el in els) { var jscode = els[el].getAttribute('onvisible'); eventQueue.push( {el:els[el], cb:Function(jscode)} ) } //eventQueue[0].cb.call(scope, args);