将 JsonRequestBehavior 设置为 AllowGet 时可能会泄露哪些“敏感信息”

Posted

技术标签:

【中文标题】将 JsonRequestBehavior 设置为 AllowGet 时可能会泄露哪些“敏感信息”【英文标题】:What 'sensitive information' could be disclosed when setting JsonRequestBehavior to AllowGet 【发布时间】:2014-02-22 13:05:25 【问题描述】:

当我是returning Json(使用内置的MVC JsonResult helper)时,每次从浏览器的地址栏中测试新的URL 时,我都会遇到同样的错误:

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

这一次,我想知道GET 请求暴露了POST 请求没有暴露的究竟是什么?

【问题讨论】:

【参考方案1】:

默认情况下,ASP.NET MVC 框架不允许你响应 带有 JSON 有效负载的 GET 请求,因为恶意用户有可能通过称为 JSON 劫持的过程访问有效负载。您不想在 GET 请求中使用 JSON 返回敏感信息。

如果您需要发送 JSON 以响应 GET,并且不暴露敏感数据,您可以通过将 JsonRequestBehavior.AllowGet 作为第二个参数传递给 Json 来明确允许该行为 方法。

  [HttpGet] //No need to decorate, as by default it will be GET
  public JsonResult GetMyData()  
    var myResultDataObject = buildMyData(); // build, but keep controller thin
    // delegating buildMyData to builder/Query Builder using CQRS makes easy :)
    return Json(myResultDataObject, JsonRequestBehavior.AllowGet);
  

这里有一篇来自 Phil Haack JSON Hijacking 的有趣文章,关于为什么不使用 Json 和 GET 方法

【讨论】:

很棒的帖子。应该使用 HTTPS 的充分理由。 我认为 HTTPS 在这里没有帮助。【参考方案2】:

假设您的网站有一个GetUser 网络方法:

http://www.example.com/User/GetUser/32

返回 JSON 响应:

 "Name": "John Doe" 

如果此方法只接受 POST 请求,那么只有在使用 POST 方法向http://www.example.com/User/GetUser/32 发出 AJAX 请求时,才会将内容返回给浏览器。请注意,除非您实现了CORS,否则浏览器将保护向您发出此请求的其他域的数据。

但是,如果您随后允许 GET 请求以及使用 GET 而不是 POST 发出与上述类似的 AJAX 请求,则恶意用户可能会通过使用 script 标记将您的 JSON 包含在他们自己网站的上下文中的 html。例如在www.evil.com:

<script src="http://www.example.com/User/GetUser/32"></script>

这个 javascriptwww.evil.com 应该是没用的,因为应该没有办法读取你的 web 方法返回的对象。但是,由于旧版本浏览器(例如 Firefox 3)中的错误,JavaScript 原型对象可能被重新定义,并使www.evil.com 可以读取您的方法返回的数据。这称为 JSON 劫持。

请参阅this post 了解一些防止这种情况的方法。但是,对于现代浏览器(Firefox、Chrome、IE)的较新版本(Firefox、Chrome、IE),这不是一个已知问题。

【讨论】:

不错的帖子,但是如果您在控制器中包含 [Authorize] 标签,则无需担心安全性。希望这段代码对某人有所帮助,Json(returnMsg, JsonRequestBehavior.AllowGet) @Dhanuka777:不幸的是,这不是真的。如果该方法具有副作用(例如www.example.com/User/DeleteUser/32),则可能会发生CSRF 攻击,因为请求将包含身份验证所需的cookie,因为它们来自受害者的机器。对于非常旧的浏览器,[Authorize] 也不会使您免受此处详述的攻击 - 这是用户自己访问www.evil.com,因此www.evil.comwww.example.com 发出的请求将包含授权cookie。跨度> 如果操作有任何副作用,则永远不应该使用 GET 方法调用它——惯例是使用 GET 仅用于读取数据,所有副作用操作都应使用 POST、PUT、DELETE等。换句话说,我只是认为这个“敏感信息”错误信息具有误导性。如果开发人员按照应有的方式使用 GET 方法,那么一切都很好! :) 我不确定它仍然有什么不同。它不像 post 比 get 更受保护或加密。它仍然只是纯文本。我可以像通过任何工具发送请求一样轻松地发送请求,并且仍然可以返回相同的纯文本信息。恶意用户也可以轻松地在他们自己的网站上编写任何服务器端代码来发帖。 @Castrohenge:不,因为这需要设置一个标头,该标头不会与脚本 src 的 GET 请求一起发送。【参考方案3】:

在您的退货中使用以下内容:

return this.Json("you result", JsonRequestBehavior.AllowGet);

【讨论】:

这实际上如何回答 OP 的问题?这个答案所做的就是告诉大家如何绕过异常.. 是的,使用它.. 这就像尝试用空捕获来捕获。不要使用这些人(在您了解风险之前)。 -1'd 告诉人们忽略安全警告而不至少解释后果是不负责任的。 -1【参考方案4】:

当我们想从 MVC 应用程序向客户端返回一个 json 对象时,我们应该在返回一个对象时显式指定 JsonRequestBehavior.AllowGet。因此,我返回如下的 json 数据来解决这个问题:

    return Json(yourObjectData, JsonRequestBehavior.AllowGet);

【讨论】:

【参考方案5】:

您必须像这样使用 JsonRequestBehavior.AllowGet 进行 Json 响应:

return Json(YourObject, JsonRequestBehavior.AllowGet);

【讨论】:

【参考方案6】:

return Json("Success", JsonRequestBehavior.AllowGet)

【讨论】:

以上是关于将 JsonRequestBehavior 设置为 AllowGet 时可能会泄露哪些“敏感信息”的主要内容,如果未能解决你的问题,请参考以下文章

此请求已被阻止,因为当用在 GET 请求中时,会将敏感信息透漏给第三方网站。若要允许 GET 请求,请将 JsonRequestBehavior 设置为 AllowGet。

为啥需要 JsonRequestBehavior?

webapi 中的错误 - 无法从“System.Web.Mvc.JsonRequestBehavior”转换为“Newtonsoft.Json.JsonSerializerSettings”

ASP.NET Core - 当前上下文中不存在名称“JsonRequestBehavior”

如何格式化json数组

jquery 关于 4 种提交的部分归纳