なぜJsonRequestBehaviorが必要なのですか?


384

なぜJson Request Behavior必要なのですか?

HttpGetリクエストを自分のアクションに制限したい場合は、[HttpPost]属性でアクションを装飾できます

例:

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

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

なぜ[HttpPost]十分ではないのですか?
なぜフレームワークは、私たちが持ってJsonRequestBehavior.AllowGetいるすべてのforで「バグ」を引き起こしJsonResultます。getリクエストを拒否する場合は、HttpPost属性を追加します。


stackoverflow.com/questions/1625671/…によく似ています(これは自分の質問を検索しているのに
気づきましたが

GETはべき等であることになっているのに対し、POSTはそうではないからです。GET-> POSTを行うことにより、インターフェースのセマンティクスを変更します。
リズム

19
どこにでも粗末な引数を追加する必要がないと、コードがきれいすぎるように見えるからです。
John Shedletsky、2015年

回答:


276

MVCはデフォルトDenyGetで、JSONリクエストを含む非常に特定の攻撃からユーザーを保護し、HTTP GETエクスポージャーを許可することの影響が発生する前に考慮される可能性を高めます。

手遅れになるかもしれないとき、これはその後に反対です。

注:アクションメソッドが機密データを返さない場合は、取得を許可しても安全です。

Wrox ASP.NET MVC3の本をさらに読む

デフォルトでは、ASP.NET MVCフレームワークでは、JSONペイロードを使用してHTTP GETリクエストに応答することはできません。GETへの応答としてJSONを送信する必要がある場合は、Jsonメソッドの2番目のパラメーターとしてJsonRequestBehavior.AllowGetを使用して、動作を明示的に許可する必要があります。ただし、悪意のあるユーザーがJSONハイジャックと呼ばれるプロセスを介してJSONペイロードにアクセスできる可能性があります。GETリクエストでJSONを使用して機密情報を返したくない場合。詳細については、http://haacked.com/archive/2009/06/24/json-hijacking.aspx/にある Philの投稿またはこのSO投稿を参照して ください

ハック、フィル(2011)。Professional ASP.NET MVC 3(Wrox Programmer to Programmer)(Kindle Locations 6014-6020)。Wrox。キンドル版。

関連するStackOverflowの質問

最近のブラウザー(Firefox 21、Chrome 27、またはIE 10以降)では、これは脆弱性ではなくなりました。


20
しかし、問題は残っています。なぜ[HttpPost]では不十分なのですか?
gdoronはモニカ

4
それで十分だと思います。AllowGetが必要になるのは、HttpGetの結果としてデータを渡すことを許可する場合のみです。1つのパラメーターでJson(data)を呼び出す場合、DenyGetがデフォルトです。
danludwig

11
これが私の質問です。フレームワークがJsonRequestBehavior.AllowGet、私が持っているすべてのJsonResultで「バグ」を引き起こす理由。getリクエストを拒否する場合は、HttpPost属性を追加します。
gdoronはモニカ

35
これは、このあいまいな脆弱性に気づいていない人が多いためだと思います。リクエストを拒否する場合は、[HttpPost]を使用します。ただし、MVCの作成者は、この種の攻撃に対する最初からの保護レイヤーを提供しています。2番目の引数を追加するために努力する必要があるので、その時間を取って、公開しているデータとその機密性を考慮する必要があります。
danludwig

11
では、APIを整理し、 "RESTful"インターフェースに動詞の混乱を追加して、潜在的なクライアント主導の脆弱性を回避しますか?これはひどいようです...しかし、私は議論に感謝します。
ノーマンH

59

自分で簡単にするために、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);
    }
}

そしてあなたの行動にそれを使用してください

[AllowJsonGet]
public JsonResult MyAjaxAction()
{
    return Json("this is my test");
}

4
さらに、これをRegisterGlobalFiltersのデフォルトフィルターとして設定できます:filters.Add(new AllowJsonGetAttribute())。ただし、フィルターはすべてのアクションメソッドに適用されるため、例外を削除する必要があります。
Vortex852456

8

デフォルトではJsonresult "Deny get"

以下のようなメソッドがあるとします

  [HttpPost]
 public JsonResult amc(){}

デフォルトでは「Deny Get」です。

以下の方法で

public JsonResult amc(){}

getまたはgetを使用する必要がある場合は、JsonRequestBehavior.AllowGetを使用する必要があります。

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

5

AllowJsonGetAttributeをmvc-controllers(個々のアクションメソッドだけでなく)に適用できるようにすることで、@ 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);
    }
}

2

あなたはそれを必要としません。

アクションにHttpPost属性がある場合は、の設定に煩わされることなく、属性JsonRequestBehaviorなしでオーバーロードを使用する必要はありません。JsonRequestBehavior列挙型のない各メソッドにはオーバーロードがあります。どうぞ:

JsonRequestBehaviorなし

protected internal JsonResult Json(object data);
protected internal JsonResult Json(object data, string contentType);
protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding);

JsonRequestBehaviorを使用

protected internal JsonResult Json(object data, JsonRequestBehavior behavior);
protected internal JsonResult Json(object data, string contentType, 
                                   JsonRequestBehavior behavior);
protected internal virtual JsonResult Json(object data, string contentType, 
    Encoding contentEncoding, JsonRequestBehavior behavior);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.