web-dev-qa-db-ja.com

ASP.NETMVC偽造防止トークンは安全ではありません

Sslなしでサーバーにリクエストを送信すると、MVC3フレームワークによって生成された検証トークンキーがプレーンテキストで実際に表示されます。

このキーは、_RequestVerificationToken_Lw__というCookieに保存されます。

混合セキュリティ環境では、非sslサイトへの最初の要求でサーバーに送信されたプレーンテキストでこのトークンを確認することが実際に可能です。このトークンは、ユーザーのセッションの間も静的です。次に、Cookieがプレーンテキストでスローされるため、攻撃者が簡単に盗む可能性がある場合に、このトークンを使用するとどうなりますか。

このCookieは安全であるとマークされ、プレーンテキストで送信されるべきではありませんか?または、少なくとも、安全な情報がSSLチャネルから漏れないように、すべての要求で再生成されますか?

私はMVC3 AntiForgeryWorkerクラスでこのブロックについて話している

private string GetAntiForgeryTokenAndSetCookie(HttpContextBase httpContext, string salt, string domain, string path)
{
  string forgeryTokenName = AntiForgeryData.GetAntiForgeryTokenName(httpContext.Request.ApplicationPath);
  AntiForgeryData token = (AntiForgeryData) null;
  HttpCookie httpCookie = httpContext.Request.Cookies[forgeryTokenName];
  if (httpCookie != null)
  {
    try
    {
      token = this.Serializer.Deserialize(httpCookie.Value);
    }
    catch (HttpAntiForgeryException ex)
    {
    }
  }
  if (token == null)
  {
    token = AntiForgeryData.NewToken();
    string str = this.Serializer.Serialize(token);
    HttpCookie cookie = new HttpCookie(forgeryTokenName, str)
    {
      HttpOnly = true,
      Domain = domain
    };
    if (!string.IsNullOrEmpty(path))
      cookie.Path = path;
    httpContext.Response.Cookies.Set(cookie); //Ma, Why isn't this marked as "SECURE"
  }
  return this.Serializer.Serialize(new AntiForgeryData(token)
  {
    Salt = salt,
    Username = AntiForgeryData.GetUsername(httpContext.User)
  });
}
12
Alwyn

CSRF攻撃から保護するための最適なソリューションは、常にSSLを使用することです。 SSLがないと、はい、nonce-と呼ばれる-はMITM攻撃に対して脆弱です。 Cookieを使用してナンスを保存する場合、CookieはHTTPのみとしてマークする必要があります。これにより、JavaScriptがCookieを読み取ることができなくなります。また、Cookieに加えて、すべての<input type="hidden" value="nonce">内でナンスを<form>タグとしてレンダリングする必要があります。

ブラウザ自体にアクセスできる人なら誰でもナンスを読み取ることができます。リプレイ攻撃を防ぐ唯一の方法は、サーバーによって初めて検証された後、ナンスを最初に期限切れにすることです。ただし、このアプローチでは、ユーザーが戻るボタンを使用して同じナンスでリクエストを再送信すると、ひどいユーザーエクスペリエンスが発生する可能性があります。 ASP.NET MVCに組み込まれているアンチCSRF保護メカニズムを使用しているため、ナンスを1回だけ使用できるように動作を変更するのは簡単ではない場合があります。 (編集:ASP.NET MVCが実際にこれを非常に簡単にすることを知らせてくれた以下のLeviに感謝します)

ナンスの生成と検証をより適切に制御したい場合は、JuniorRouteフレームワークで行ったように、独自の実装をロールすることをお勧めします。実際、 JuniorRouteのソースコード を見て、私がどのように実装したかを確認してください。 StackOverflowの投稿にはコードが多すぎます。

9
NathanAldenSr

それはあなたがそこに持っているかなり炎症的な質問のタイトルです。

組み込みのMVC偽造防止機能は、アプリケーションが構成されているのと同じくらい安全です。 Web.configで<httpCookies requireSSL="true" />が設定されている場合、Response.Cookiesに書き込まれるすべてのCookieは自動的に「セキュア」修飾子でマークされます( MSDNドキュメントを参照 )。このスイッチが設定されている場合、MVCの偽造防止Cookieもこの動作を取得します。

これを応答の HSTSヘッダーの設定 のような他の機能と組み合わせると、基本的に、ブラウザーがプレーンテキストチャネルを介して機密データを送信しないことが保証されます。

さらに、偽造防止システムでは、トークンにカスタムデータを保存できます。また、トークンが検証されたときに、カスタムデータを検証するためのコールバックを受け取ることができます。詳細については、 AntiForgeryConfig.AdditionalDataProvider を参照してください。

25
Levi

マイテイク

a)フォームの送信は、以下の比較に基づいて偽造されていないと見なされます。

  • __RequestVerificationToken cookie

  • __RequestVerificationTokenフォームフィールド。

2つの値は、ある種の対称的に一致しているため、同じではありません。

b)一部のアプリケーションはhttpsを使用しないため、フレームワークによってCookieをデフォルトのmust-use-secure-channelとしてマークすることはできません。

c)__ RequestVerificationTokenの実装は、CSRFに対する保護であり、有効なユーザーがプロセスメモリにスヌーピングするのを助けることはできません:p。

0
Pushpendra