使用 JavaScript eval 解析 JSON
问题:我正在使用 eval 解析来自我的 WebMethod 之一的 JSON 返回值。
我不想添加jquery-json,因为传输量已经相当大了。 所以我用eval解析JSON返回值。
现在有传言说这是不安全的。为什么 ?
没有人可以修改 JSOn 返回值,除非他们破解了我的服务器,在这种情况下我无论如何都会遇到更大的问题。
如果他们在本地执行,JavaScript 只会在他们的浏览器中执行。
所以我看不出问题出在哪里。
有人可以用这个具体的例子来阐明这一点吗?
function OnWebMethodSucceeded(JSONstrWebMethodReturnValue)
{
var result=eval('(' + JSONstrWebMethodReturnValue + ')')
... // Adding result.xy to a table
}
Question: I'm using eval to parse a JSON return value from one of my WebMethods.
I prefer not to add jquery-json because the transfer volume is already quite large.
So I parse the JSON return value with eval.
Now rumors go that this is insecure. Why ?
Nobody can modify the JSOn return value unless they hack my server, in which case I would have a much larger problem anyway.
And if they do it locally, JavaScript only executes in their browser.
So I fail to see where the problem is.
Can anybody shed some light on this, using this concrete example?
function OnWebMethodSucceeded(JSONstrWebMethodReturnValue)
{
var result=eval('(' + JSONstrWebMethodReturnValue + ')')
... // Adding result.xy to a table
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根本问题是
eval
可以运行任何 JavaScript,而不仅仅是反序列化 JSON 格式的数据。这就是使用它处理来自不可信或半可信源的 JSON 时存在的风险。将 JSON 括在括号中的常见技巧不足以确保不执行任意 JavaScript。考虑一下这个“JSON”,它实际上不是:如果您将其放在变量
x
中并执行以下操作:...您会看到一个警报 - JavaScript 运行了。安全问题。
如果您的数据来自可信来源(听起来确实如此),我不会太担心。也就是说,您可能对 此处 Crockford 的讨论感兴趣(Crockford 是 JSON 的发明者,也是一般知识渊博的 JavaScript 人)。 Crockford 还在此页面上提供了至少三个公共域解析器,您可以考虑使用:他的 json2 .js 解析器和字符串生成器,缩小后大小仅为 2.5k,但仍然使用
eval
(只是首先采取一些预防措施);他的 json_parse.js,这是一个不使用eval
的递归下降解析器;和他的 json_parse_state.js,一个状态机解析器(同样不使用eval
)。所以你要选择你的毒药。 (向 Camilo Martin 指出最后两个替代方案表示感谢。)The fundamental issue is that
eval
can run any JavaScript, not just deserialize JSON-formatted data. That's the risk when using it to process JSON from an untrusted or semi-trusted source. The frequent trick of wrapping the JSON in parentheses is not sufficient to ensure that arbitrary JavaScript isn't executed. Consider this "JSON" which really isn't:If you had that in a variable
x
and did this:...you'd see an alert -- the JavaScript ran. Security issue.
If your data is coming from a trusted source (and it sounds like it is), I wouldn't worry about it too much. That said, you might be interested in Crockford's discussion here (Crockford being the inventor of JSON and a generally-knowledgeable JavaScript person). Crockford also provides at least three public domain parsers on this page you might consider using: His json2.js parser and stringifier, which when minified is only 2.5k in size, but which still uses
eval
(it just takes several precautions first); his json_parse.js, which is a recursive-descent parser not usingeval
; and his json_parse_state.js, a state machine parser (again not usingeval
). So you get to pick your poison. (Shout out to Camilo Martin for pointing out those last two alternatives.)JSON 解析和编码越来越多地在现代浏览器中原生可用,[维基百科参考]为您的应用程序提供安全的 JSON 功能,无需加载额外的库。
您可以通过执行以下操作来测试本机 JSON 支持:
您应该加载一个 JSON 解析库,例如 Douglas Crockford 的库(由上面的 TJ Crowder 链接)或通过框架为没有本机支持的浏览器提供的功能。 (但您至少应该在支持它的浏览器中使用本机 JSON,以保护幸运地拥有现代浏览器的用户)
请记住,JSON 是 JavaScript 语法的子集,因此在 JavaScript eval 语句中工作的字符串可能无法正常工作JSON 解析。您可以使用 JSLint (http://www.jslint.com/) 测试 JSON 字符串是否有错误。
Increasingly, JSON parsing and encoding is available natively in modern browsers, [wikipedia reference] This gives your application secure JSON functionality without needing to load an additional library.
You can test for native JSON support by doing something like this:
You should load up a JSON parsing library like Douglas Crockford's one (linked by T.J. Crowder, above) or functionality available via a framewok for browsers that don't have native support. (But you should at least use native JSON in browsers that support it, to protect users lucky enough to have modern browsers)
Bear in mind, JSON is a subset of JavaScript's syntax so strings that work in an JavaScript eval statement may not work in proper JSON parsing. You can test your JSON strings for errors using JSLint (http://www.jslint.com/).