web-dev-qa-db-ja.com

ASP.NET WebFormsのOWASPでのCSRFの2つのソリューション

OWASPからの2つのソリューションの違いについて混乱しています ASP.NET Web Fromsガイダンス

解決策1:

ビューステートは必ずしもWeb開発に適しているとは限りませんが、ビューステートを使用するとCSRFを軽減できます。 ViewStateをCSRF攻撃から保護するには、ViewStateUserKeyを設定する必要があります。

protected override OnInit(EventArgs e) {
    base.OnInit(e); 
    ViewStateUserKey = Session.SessionID;
} 

解決策2:

Viewstateを使用しない場合は、ASP.NET Webフォームのデフォルトテンプレートのデフォルトマスターページで、二重送信Cookieを使用した手動のCSRF防止トークンを探します。

private const string AntiXsrfTokenKey = "__AntiXsrfToken";
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
private string _antiXsrfTokenValue;
protected void Page_Init(object sender, EventArgs e)
{
    // The code below helps to protect against XSRF attacks
    var requestCookie = Request.Cookies[AntiXsrfTokenKey];
    Guid requestCookieGuidValue;
    if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
    {
       // Use the Anti-XSRF token from the cookie
       _antiXsrfTokenValue = requestCookie.Value;
       Page.ViewStateUserKey = _antiXsrfTokenValue;
    }
    else
    {
       // Generate a new Anti-XSRF token and save to the cookie
       _antiXsrfTokenValue = Guid.NewGuid().ToString("N");
       Page.ViewStateUserKey = _antiXsrfTokenValue;
       var responseCookie = new HttpCookie(AntiXsrfTokenKey)
       {
          HttpOnly = true,
          Value = _antiXsrfTokenValue
       };
       if (FormsAuthentication.RequireSSL && Request.IsSecureConnection)
       {
          responseCookie.Secure = true;
       }
       Response.Cookies.Set(responseCookie);
    }
    Page.PreLoad += master_Page_PreLoad;
}

protected void master_Page_PreLoad(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
       // Set Anti-XSRF token
       ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;
       ViewState[AntiXsrfUserNameKey] = Context.User.Identity.Name ?? String.Empty;
    }
    else
    {
       // Validate the Anti-XSRF token
       if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue || 
          (string)ViewState[AntiXsrfUserNameKey] != (Context.User.Identity.Name ?? String.Empty))
       {
          throw new InvalidOperationException("Validation of Anti-XSRF token failed.");
       }
    }
}

私が得られなかったのは、最初のアプローチに関するこのコメントです。「ViewStateをCSRF攻撃から保護するには、ViewStateUserKeyを設定する必要があります。」 2番目のソリューションのコードを見ると、コードでViewSateを明確に使用しているので、作成者が「ViewStateを使用してコントロール状態を永続化する」ことを意味していると思います。したがって、ページまたはマスターページでEnableViewStateがfalseに設定されている場合、最初のアプローチはまったく機能しませんか?

更新:OWASP Anti CSRF Tokens ASP.NETの2番目のアプローチに関するコメント

Visual Studio 2012以降、CSRF防止メカニズムが改善されました。

新しい戦略では引き続き、ViewStateをCSRF保護のメインエンティティとして使用しますが、トークン(GUIDとして生成できます)も使用するため、ViewStateUserKeyをセッションIDではなくトークンに設定し、それをトークンに対して検証できます。クッキー。

3
Paul L

少なくとも私にとってトリッキーな部分は、成功/機能する例のCSRF攻撃を構築することです。その後、両方のアプローチを実装し、それらが機能していることを確認して実際にCSRF攻撃を軽減することは簡単です。

ViewStateUserKeyのみを使用する最初のアプローチは、ページレベルでもWebアプリレベルでもenableViewStateをオフにしても影響を受けないようです。非表示のViewStateはレンダリングされたHTMLに残っており、ViewStateをエンコードするプロセスはまだ残っているので、単にViewStateをオフにするだけではViewStateUserKeyをオフにできません。

一方、2番目のアプローチはAntiXsrfTokenKeyのストレージにViewStateを使用しているため、ViewStateが無効になっていると動作しなくなります。そのため、そのOWASPページからのコメントは間違っているか、少なくとも誤解を招く可能性があります。OWASPの他のページからの他のコメントは、はるかに優れて明確です。

1
Paul L