ajax 请求返回一个标准 JSON 数组,其中填充了我的用户输入。输入已经过清理,使用 eval() 函数,我可以轻松创建我的 javascript 对象并更新我的页面......
所以这就是问题所在。无论我多么努力地清理输入,我都宁愿不使用 eval() 函数。我已经检查了谷歌的方法来使用“没有 eval 的 AJAX 中的 JSON”并且已经运行了一堆不同的方法......
我应该使用哪一个?是否有一种标准的、经过验证的安全方式来执行此操作?
ajax 请求返回一个标准 JSON 数组,其中填充了我的用户输入。输入已经过清理,使用 eval() 函数,我可以轻松创建我的 javascript 对象并更新我的页面......
所以这就是问题所在。无论我多么努力地清理输入,我都宁愿不使用 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 没有验证
是否有一种标准的、经过验证的安全方式来执行此操作?
在即将推出的 JavaScript 的 ECMAScript 3.1 版本中,有一种建议的标准方法:JSON.parse。
它将在 IE8、Firefox 3.1/3.5 以及很可能在未来的其他流行浏览器中得到支持。同时,您可以回退到或独占使用 eval()。邪恶可能是也可能不是;当然它会比 JSON.parse 慢。但这是当今解析 JSON 的常用方法。
如果攻击者能够将恶意 JavaScript 注入到您通过 JSON 吐出的内容中,那么您需要担心的问题比 eval-is-evil 更大。
我想说,一旦输入被清理, eval 是最好的方法。如果您的服务器受到威胁,人们无论如何都可以向客户端发送他们想要的任何脚本。因此,进行评估并不是很大的安全风险。如果您担心人们会在数据包到达客户端之前对其进行操作,那么同样可以修改脚本本身。
不用担心评估。但是请确保将其包装在 try...catch 块中,这样如果您的 JSON 被破坏,您的用户就不会收到 JS 错误。
:)
为了安全地将 JSON 转换为 JS 对象,您应该使用 JSON 解析器,例如此库提供的 JSON.parse() 函数。
与命令设计模式比较: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
设想:
假设您在各种文档元素的标记代码中使用单个属性,例如属性onvisible
<img src="" onvisible="src='http://www.example.com/myimg.png';">
您想获取具有此属性的所有元素,将 onvisible-content-string 转换为闭包并将其放入 EventHandler 队列中。这就是 JS Function 构造函数发挥作用的地方。
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);