【问题标题】:Why json hijacking can be prevented using POST method?为什么使用 POST 方法可以防止 json 劫持?
【发布时间】:2020-09-13 22:03:20
【问题描述】:

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

此请求已被阻止,因为敏感信息可能会被 在 GET 请求中使用时向第三方网站披露。 要允许 GET 请求,请将 JsonRequestBehavior 设置为 AllowGet。

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

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

【问题讨论】:

  • 看完文章,我想知道我们是否正确设置了服务器中的CORS和cookie域是否仍然存在问题
  • 从文章中可以看出,漏洞利用似乎使用了<script src=""> 标签来欺骗浏览器从服务器请求 JSON。由于script src 总是使用 GET,如果服务器没有响应 GET,则漏洞利用会失败。因此,POST 应该是安全的。
  • 是的,您可以从脚本发出 POST 请求,但除非服务器响应 GET 请求,否则此特定漏洞将不起作用。
  • 不,<script src> 标签欺骗浏览器从目标服务器下载 JSON 数组。

标签: javascript json ajax security csrf


【解决方案1】:

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

更新

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

您可以找到一篇文章here,它描述了 JSON 劫持攻击步骤。如下:

  • 第 1 步:让经过身份验证的用户访问恶意页面。
  • 第 2 步:恶意页面将尝试访问用户登录的应用程序中的敏感数据。这可以通过在 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,则站点可以通过对象原型设置器获取敏感数据。 (请记住,攻击者会尝试使用 SCRIPT 标签而不是 AJAX 请求,因为同源策略不适用于脚本标签。请参阅Cross-origin network access 规则。)

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

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

【讨论】:

    【解决方案2】:

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

    更新答案

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

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

    这在其他related questions中也有引用

    【讨论】:

    • 感谢您的回答,我阅读了您包含的文章...我无法找到它描述如何使用 CORS 策略对 GetPost 方法进行不同处理的地方。 .你能指出来吗?
    • @HoomanBahreini,我的意思是引用 CORS 页面作为 CORS 是什么的参考,而不是引用 GETPOST 之间差异的页面。
    • 感谢您的澄清......正如赏金中所述,我正在寻找一个有信誉的来源来澄清为什么PostGet在json方面的行为不同劫持。感谢您解释这是因为 CORS 政策,但我无法在文档中找到 GetPost 的 CORS 政策有何不同/为何不同。
    • @HoomanBahreini 您没有在问题中说明任何有关信誉良好的来源的信息。你只是问“为什么”。
    • @thelr OP 在上面的蓝色框中提到了这一点,而不是在问题中。
    【解决方案3】:

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

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

    浏览器只会盲目地相信你,如果你从任何你知道你在做什么的地方加载这样的资源,它会为你获取它(否则像 CDN 这样的东西将不起作用)而不是 XHR 请求

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

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

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

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

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

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

    您可能会想啊,我只是将form 目标设置为iframe 但是JavaScript 不允许您访问该iframe 中的任何内容。

    这有意义吗?

    【讨论】:

      【解决方案4】:

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

      this articlethis SO answer 中阅读有关 JSON 黑客攻击漏洞的更多信息。

      【讨论】:

        猜你喜欢
        • 2018-02-02
        • 1970-01-01
        • 1970-01-01
        • 2011-08-27
        • 1970-01-01
        • 2019-05-08
        • 2012-08-27
        • 2012-05-19
        相关资源
        最近更新 更多