使用JavaScript eval解析JSON
问题:我正在使用eval来解析我的一个WebMethods的JSON返回值。
我不想添加jquery-json,因为传输量已经非常大了。
所以我用eval解析JSON返回值。
现在谣言说这是不安全的。为什么?
除非他们破解我的服务器,否则没有人可以修改JSOn返回值,在这种情况下,无论如何我都会遇到更大的问题。
如果他们在本地执行,JavaScript只能在他们的浏览器中执行。
所以我没有看到问题所在。
使用这个具体的例子可以解释一下吗?
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
}
根本问题是 eval
可以运行任何JavaScript,而不仅仅是反序列化JSON格式的数据。使用它来处理来自不受信任或半可信来源的JSON时存在风险。将JSON包装在括号中的常见技巧不足以确保不执行任意JavaScript。考虑这个JSON,它实际上不是:
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:
function(){alert('Hi')})(
如果你在变量 x
中有这个并且做了这个:
If you had that in a variable x
and did this:
var result = eval("(" + x + ")");
...你会看到一个警告 - JavaScript运行。安全问题。
...you'd see an alert -- the JavaScript ran. Security issue.
如果您的数据来自可靠的来源(听起来像是这样),我不会太担心。那就是说,您可能对Crockford的讨论感兴趣这里(Crockford是JSON的发明者和知识渊博的JavaScript人员。)Crockford还提供至少三个公共域解析器这个页面:他的json2.js解析器和字符串化器,它在缩小时只是大小为2.5k,但仍然使用 eval
(首先需要采取一些预防措施);他的json_parse.js,这是一个递归下降的解析器,不使用 eval
;和他的json_parse_state.js,状态机解析器(再次不使用 eval
)。所以你可以选择你的毒药。 (向 Camilo Martin 致敬,指出最后两种选择。)
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 using eval
; and his json_parse_state.js, a state machine parser (again not using eval
). So you get to pick your poison. (Shout out to Camilo Martin for pointing out those last two alternatives.)