为什么需要JsonRequestBehavior?

gdo*_*ica 369 .net c# security asp.net-mvc asp.net-mvc-3

为什么Json Request Behavior需要?

如果我想将HttpGet请求限制为我的操作,我可以使用该[HttpPost]属性修饰操作

例:

[HttpPost]
public JsonResult Foo()
{
    return Json("Secrets");
}

// Instead of:
public JsonResult Foo()
{
    return Json("Secrets", JsonRequestBehavior.AllowGet);
}
Run Code Online (Sandbox Code Playgroud)

为什么[HttpPost]不够?
为什么框架会JsonRequestBehavior.AllowGet为我们所拥有的每一个"捣乱"我们JsonResult.如果我想拒绝获取请求,我将添加该HttpPost属性.

dan*_*wig 270

MVC默认为DenyGet保护您免受涉及JSON请求的非常特定的攻击,以改善允许HTTP GET暴露的影响在允许它们发生之前被考虑的可能性.

这可能为时已晚,这与之后相反.

注意:如果您的操作方法没有返回敏感数据,那么允许获取是安全的.

从我的Wrox ASP.NET MVC3书中进一步阅读

默认情况下,ASP.NET MVC框架不允许您使用JSON有效内容响应HTTP GET请求.如果您需要发送JSON以响应GET,则需要使用JsonRequestBehavior.AllowGet作为Json方法的第二个参数来显式允许该行为.但是,恶意用户有可能通过称为JSON Hijacking的进程获得对JSON有效负载的访问权限.您不希望在GET请求中使用JSON返回敏感信息.有关详细信息,请参阅http://haacked.com/archive/2009/06/24/json-hijacking.aspx/上的 Phil帖子 或此SO帖子.

哈克,菲尔(2011年).专业的ASP.NET MVC 3(Wrox程序员到程序员)(Kindle Locations 6014-6020).Wrox的.Kindle版.

相关的StackOverflow问题

对于大多数最近的浏览器(从Firefox 21,Chrome 27或IE 10开始),这不再是一个漏洞.

  • 我认为这是因为没有很多人意识到这个不起眼的漏洞.你说如果你想拒绝这个请求,你会用[HttpPost]来做.然而,MVC作者正在为您提供一层防范此类攻击的保护.由于您需要努力添加第二个参数,因此您应该花时间考虑要暴露的数据以及它的敏感程度. (35认同)
  • 但问题仍然存在:为什么[HttpPost]不足够? (20认同)
  • 这是我的问题.为什么框架使用`JsonRequestBehavior.AllowGet`为我所拥有的每个JsonResult"窃听"我们.如果我想拒绝获取请求,我将添加`HttpPost`属性. (11认同)
  • 那么现在我们混乱了我们的API并将动词混淆添加到"RESTful"接口以解决潜在的CLIENT驱动的漏洞?这看起来很可怕......但我很感激讨论. (9认同)
  • 我认为这已经足够了.当您希望允许数据作为HttpGet的结果传递时,您只需要AllowGet.如果使用1参数调用Json(数据),则DenyGet是默认值. (4认同)
  • @AndersLindén因为指向URL的脚本标记不会通过POST加载那些远程脚本,所以攻击不会成功,因为服务器仅接受该数据的POST请求。 (2认同)

Arj*_*oij 57

为了使自己更容易,您还可以创建一个actionfilterattribute

public class AllowJsonGetAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var jsonResult = filterContext.Result as JsonResult;

        if (jsonResult == null)
            throw new ArgumentException("Action does not return a JsonResult, 
                                                   attribute AllowJsonGet is not allowed");

        jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;            

        base.OnResultExecuting(filterContext);
    }
}
Run Code Online (Sandbox Code Playgroud)

并将其用于您的行动

[AllowJsonGet]
public JsonResult MyAjaxAction()
{
    return Json("this is my test");
}
Run Code Online (Sandbox Code Playgroud)

  • 此外,您可以将其设置为RegisterGlobalFilters中的默认过滤器:filters.Add(new AllowJsonGetAttribute()).但是,您必须删除Exception,因为Filter将应用于所有操作方法. (4认同)

Dee*_*jan 8

默认情况下Jsonresult"拒绝获取"

假设我们有如下方法

  [HttpPost]
 public JsonResult amc(){}
Run Code Online (Sandbox Code Playgroud)

默认情况下它是"拒绝获取".

在下面的方法中

public JsonResult amc(){}
Run Code Online (Sandbox Code Playgroud)

当您需要允许或使用get时,我们必须使用JsonRequestBehavior.AllowGet.

public JsonResult amc()
{
 return Json(new Modle.JsonResponseData { Status = flag, Message = msg, Html = html }, JsonRequestBehavior.AllowGet);
}
Run Code Online (Sandbox Code Playgroud)


XDS*_*XDS 5

通过使AllowJsonGetAttribute适用于mvc-controllers(而不仅仅是单独的action-methods)来改进@Arjen de Mooij的答案:

using System.Web.Mvc;
public sealed class AllowJsonGetAttribute : ActionFilterAttribute, IActionFilter
{
    void IActionFilter.OnActionExecuted(ActionExecutedContext context)
    {
        var jsonResult = context.Result as JsonResult;
        if (jsonResult == null) return;

        jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var jsonResult = filterContext.Result as JsonResult;
        if (jsonResult == null) return;

        jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        base.OnResultExecuting(filterContext);
    }
}
Run Code Online (Sandbox Code Playgroud)