将JsonRequestBehavior设置为AllowGet时,可能会公开哪些“敏感信息”


112

每次使用内置功能时,每次URL从浏览器的地址栏中测试新内容时,我都会遇到相同的旧错误returning JsonMVC JsonResult helper):

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

这次,我没有为确认而烦恼并解雇Fiddler来执行发布请求,而是想知道GET请求暴露了一个POST请求没有暴露的确切含义是什么?

Answers:


82

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

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

返回JSON响应:

{ "Name": "John Doe" }

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

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

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

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

有关防止这种情况的一些方法,请参见这篇文章。但是,现代浏览器的更高版本(Firefox,Chrome,IE)不是已知问题。


25
不错的帖子,但是如果您在控制器中包含[Authorize]标签,则无需担心安全性。希望这个代码可以帮助别人,JSON(returnMsg,JsonRequestBehavior.AllowGet)
Dhanuka777

17
@ Dhanuka777:不幸的是,这不是真的。如果该方法具有副作用(例如),则CSRF攻击是可能的,www.example.com/User/DeleteUser/32因为该请求将包括cookie,因为它们来自受害人的机器,因此对于身份验证是必需的。[Authorize]也救不了你无论是在一个非常古老的浏览器的情况下,这里详述的攻击-这是他们自己的访问用户www.evil.com因此请求www.evil.com使得以www.example.com将包含授权cookie。
SilverlightFox 2014年

1
而且,如果该操作有任何副作用,则永远不要使用GET方法来调用它-惯例是仅使用GET读取数据,并且所有副作用操作都应使用POST,PUT,DELETE等。换句话说,我只是认为此“敏感信息”错误消息具有误导性。如果开发人员以应有的方式使用GET方法,那么一切都很好!:)
ps_ttf

1
我不确定它仍然有什么区别。它不像post一样受get保护或加密。它仍然只是纯文本。我可以像通过任何工具发布请求一样轻松地发送请求,并且仍然可以得到相同的纯文本信息。恶意用户也可以在自己的站点上轻松编写任何服务器端代码来发布信息。
computrius

1
@Castrohenge:不,因为这需要设置一个标头,该标头不会与脚本src的GET请求一起发送。
SilverlightFox

111

在您的退货中,使用以下命令:

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

7
这实际上如何回答OP的问题?这一切的答案确实是告诉大家如何绕过例外..
eaglei22

2
是的,请使用它。就像尝试捕获一个空捕获。不要使用这些家伙(在您了解风险之前)。-1'd
sotn

6
告诉人们忽略安全警告而没有至少说明后果是不负责任的。-1
爱德华多·瓦达

58

默认情况下,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方法一起使用


2
很棒的帖子。您应该使用HTTPS的充分理由。
pqsk 2015年

6
我认为HTTPS在这里没有帮助。
肖恩·麦克米兰

10

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

    return Json(yourObjectData, JsonRequestBehavior.AllowGet);

7

您必须使用JsonRequestBehavior.AllowGet进行Json Response,如下所示:

return Json(YourObject, JsonRequestBehavior.AllowGet);

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.