为什么使用POST方法可以防止json劫持?

Why json hijacking can be prevented using POST method?

Get 方法中返回 json 时,我遇到了以下 ASP.NET MVC 错误:

This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.

显然这个漏洞被称为json劫持This article 解释说,当使用 Get 返回 json 时,网站可能会被利用。但是在 Post 方法中返回 json 是安全的。

为什么将 Get 更改为 Post 可以防止这种攻击?

将请求设置为 POST 将阻止来自其他基于 CORS policy 的域的任何请求,除非您将服务器配置为允许它,这将把这个问题变成另一个问题。 GET 另一方面,浏览器允许请求检索资源,例如 javascript 可能包含您域中的敏感数据,而且它恰好是一个数组而不是对象。

更新答案

您实际上找不到消息来源告诉您 GETPOST 请求对于 JSON Hijacking 攻击有何不同。区别实际上在于 Web 服务器和浏览器如何处理这些请求。 JSON 劫持漏洞是关于恶意网站使用您 website/app 中的端点,该端点提供 JSON 数据并响应 GET 请求(默认情况下的请求允许下载资源,例如 js、图像、文本文件),如果将其更改为 POST,它们将无法包含执行 POST<script> ] 来自 src 属性的请求,即使在脚本标记内 POST 请求也会被 CORS 策略阻止。

在现代浏览器时代,由于 CORS 政策,我们不再有此类漏洞(至少在 Jeremiah Grossman 的发现文章中提到的形式)

这在其他related questions

中也有引用

JSON 不应作为 GET 返回,因为攻击者注入 <script> 可能会窃取数据(例如,如果加载动态内容时未 HTML逃脱)。脚本是通过 GET 方法从服务器请求的,因此从服务器发送的带有 POST 的任何内容都不会是来自注入脚本的 运行。由于他们的脚本是 运行,黑客可以使用您登录的 cookie 访问您的 JSON,这是他们不应该被允许的。

详细了解 this article and this SO answer 中的 JSON 个黑客漏洞。

如果您在任何包含脚本、图像、样式表或字体的网页上打开网络面板,您会看到所有这些请求都是使用 GET HTTP 方法完成的。例如,这是对由 <script> 标记加载的文件的请求如下所示:

这是一个由 <img> 标签加载的文件示例,如下所示:

浏览器只会盲目地相信你,如果你从任何地方加载这样的资源,你知道你在做什么,它会为你获取它(否则 CDN 之类的东西将无法工作)相反XHR 请求!

XHR 请求(包括 fetch 调用)根据 CORS 策略进行检查,我相信你很熟悉那是什么。 JavaScript 将无法对位于不同域(或端口等)上的资源发出任何 XHR 请求。

所以你有两种类型的请求策略:

  1. 你使用 XHR 获取的任何内容都会根据 CORS 检查,但你可以选择你想要的任何 HTTP 请求方法
  2. 您使用 imgscriptlink 等加载的任何内容都不会根据 CORS 策略进行检查 但您仅限于 GET HTTP仅请求。浏览器还将发送所有 cookie,在这种情况下最重要的是身份验证 cookie。

这意味着如果您使用 GET 提供 JSON 数组,您可以使用 script 标签为您获取它 无论您使用哪个域在。然后,使用文章中提到的技巧,您可以 执行 数组(听起来很奇怪但确实如此)并获取敏感信息。

如果您使用 POST,攻击者无法使用 script(或任何其他)标签来执行此请求,因为他们使用 GET 请求来获取资源。

您可能会想 啊,但我可以使用 form 来做到这一点! 但您会 运行 遇到相同的 CORS 问题。如果您只是提交 form,JSON 数据将加载到当前页面,作为攻击者,您无法获取它,因为您的脚本已不存在于页面上。

您可能会想 啊,我只是将 form 目标设置为 iframe!,但是 JavaScript 不允许您访问任何内容在那个 iframe.

这有意义吗?

看到这么多人试图证明 JSON 劫持 仍然是一个安全问题,我真的很惊讶。 (当然,如果您仍然使用 Firefox 2、Opera 9 或 Safari 3,则可以)。 None 的现代浏览器长期以来都有这个问题。您在问题中提到的文章写于 2009 年。您可以查看此 post 以了解有关如何解决该问题的更多信息。而且您无需担心 JsonRequestBehavior 只需允许获取并忘记即可。

更新

抱歉,我还没有阅读赏金问题。为什么将请求更改为 post 可以防止 json 劫持?

您可以找到一篇文章 here,其中描述了 JSON 劫持攻击步骤。它是这样的:

  • 第 1 步:让经过身份验证的用户访问恶意页面。
  • 第 2 步:恶意页面将尝试从用户登录的应用程序访问敏感数据 into.This 可以通过嵌入来完成HTML 页面中的脚本标记 ,因为同源策略不适用于脚本标记

    <script src="http://<jsonsite>/json_server.php"></script>

    浏览器将向 json_server.php 发出 GET 请求,并且用户的任何身份验证 cookie 都将随请求一起发送。

    ...

您可以这样想这个场景,用户访问 www.yoursite.com 并获得身份验证。在该用户离开您的站点并转到恶意站点之后。如果恶意站点有一个 <script src="http://www.yoursite.com/some_endpoint"></script> 标签,浏览器将发出 GET 请求。如果返回的数据是 JSON,则站点可以通过对象原型 setter 获取敏感数据。 (请记住,攻击者会尝试使用 SCRIPT 标记而不是 AJAX 请求,因为同源策略不适用于脚本标记。请参阅 Cross-origin network access 规则。)

但是如果你将http://www.yoursite.com/some_endpoint的请求类型从GET更改为POST,当浏览器试图访问它时,你的服务器将拒绝它。

另外我要留下一本解释概念的旧 MVC 框架书 here