【发布时间】:2015-05-15 09:04:17
【问题描述】:
使用来自不受信任的来源(例如另一个用户)的 URL 参数调用 jQuery 的 $.getJSON() 是否安全?换句话说,使用不受信任的 URL 调用 $.getJSON() 是否安全?我会小心不要信任响应并安全地处理响应,但是调用本身会带来安全风险吗?
换句话说,我说的是这样的:
$.getJSON(url_from_user, function(...) { ... handle response safely ...});
或
$.getJSON('http://evil.com/foo.json', function(...) {...});
如果某些不受信任的用户为url_from_user 提供恶意值或有人恶意控制evil.com 站点,这是否允许代码注入或XSS?同样,假设返回的任何 JSON 对象都将得到安全处理。
我所做的更多细节和研究
documentation for getJSON 没有说明这种情况是否安全。从逻辑上讲,我希望这个场景是安全的,因为我希望 jQuery 的实现通过 XHR 下载 JSON 对象的文本,使用安全的 JSON 解析器解析这个文本,然后返回 JSON 对象。
不过,看了jQuery源码之后,我有些怀疑这是否安全。浏览the source code for jQuery,看起来这种情况可能允许 XSS。 getJSON() 的代码有点复杂(参见src/ajax.js),但它似乎选择了一个“传输”,然后用它来发送AJAX 请求。我看到src/ajax/script.js 注册了一个名为“脚本标签黑客传输”的传输。这个传输大致如下工作:它向文档添加一个脚本标签,例如<script src="http://evil.com/foo.json">,并注册一个在下载脚本执行时运行的 onload 处理程序。换句话说,如果站点由攻击者控制,“脚本标签黑客传输”从根本上是不安全的:它将攻击者控制的脚本包含到文档中并执行它。除了脚本标签 hack 传输之外,还有一个使用浏览器 XMLHttpRequest() API 的 XHR 传输。我很难遵循决定在什么条件下使用“脚本标签黑客”传输的曲折逻辑。
那么,回到我最初的问题,使用用户提供的 URL 调用 $.getJSON() 是否安全?如果它在某些条件下可能不安全,那么在什么条件下(例如浏览器版本)它是安全/不安全的?
【问题讨论】:
-
如果用户自己指定该 URL,那么除了他们自己之外,还有谁可能会受到任何可能的 XSS 或任何伤害?或者您是否打算也为 其他 用户请求这些 URL,例如用户 A 输入 URL,而用户 B 在访问该站点时获得显示的结果……?
-
@CBroe,是的,是后者。您可以将“用户提供”视为“来自不受信任的来源”的同义词。您列出的场景将是如何发生这种情况的一个示例。我已经编辑了我的问题,希望能更清楚地说明这一点。现在清楚了吗?
-
嗯,有两种情况——要么在 URL 下提供的数据是有效的 JSON 数据,然后它只取决于你如何处理这些数据;或者不是——在这种情况下,它根本不应该被处理。也许是第三种,其中 URL 包含某种代码,该代码会触发某些浏览器中导致漏洞的错误 - 但您可能会遇到用户提供的 any 类型的 URL,甚至一些简单的外部图像。也许请求该 URL 服务器端,检查数据的有效性,然后才通过您的服务器将其传递给客户端......?
-
@CBroe,您是否阅读了我的问题中的倒数第二段?我知道这是很多文字,但我认为它直接解决了您的评论。您列出了两个或三个可能的场景,但这些并不是唯一可能的场景。另一种可能性是 jQuery 本身 做了一些引入 XSS 的事情,而不管我对数据做了什么。事实上,我在我的问题中详细解释了为什么看起来可能是这种情况——或者,至少,我不能排除这种可能性。 (出于与您详述的相同原因,让我们将可能的假设浏览器错误视为超出范围。)
-
好吧,插入脚本元素的方法通常用于规避 SOP——您可以嵌入任何来源的脚本,而 XMLHttpRequest 只能从同一来源加载数据,或者启用 CORS 的资源。如果您可以限制将用于满足这些条件的 URL,那么您可以使用 XMLHttpRequest 请求它们,而不是插入可能有害的脚本元素;如果不是,我认为通过您可以预先检查内容的服务器代理请求可能是唯一的“安全”选项。
标签: jquery json security xss getjson