-
Notifications
You must be signed in to change notification settings - Fork 0
MS_CSRFCountermeasures
- 戻る(Webアプリケーション脆弱性対策、脆弱性対策のポイント)
- CSRF(XSRF)対策の実装方針
- SameSite属性
- CSRF(XSRF) は利用中のブラウザから攻撃者により
任意の認証済みリクエストを発生させる攻撃方法で、
任意の情報の更新処理を送り付ける事が出来る。 - ASP.NETでの CSRF(XSRF) 対策方針について纏める。
移行メモ(用語): CSRF = Cross-Site Request Forgery。
XSS(Cross-Site Scripting)と紛らわしいため、
Microsoft は XSRF と表記することが多い。攻撃の本質は
**「ブラウザが Cookie を自動で送ってしまう」**ことにある。
ユーザーが罠サイトを踏むと、罠サイト上の form が
正規サイトへ POST し、ブラウザが正規サイトの Cookie を添えてしまう。
サーバーから見ると正規の認証済みリクエストと区別がつかない。
案件依存だが・・・。
-
POST
ViewStateのViewStateUserKeyに
セッション ID を割り当てる方法がメジャー。 -
GET
- 攻撃しやすいので QueryString で予期せぬ CRUD 等の操作がされないように作る。
- 具体的には、画面の初期表示のみに GET を使用するなどする。
-
POST
ValidateAntiForgeryToken属性とHtml.AntiForgeryTokenヘルパを使う。 - GET: 同上。
- 主に、業務系 SPA の裏の WebAPI は同様に対応が必要になる。
-
Cookie に設定した
X-CSRF-TOKENを、HTTP ヘッダに設定する方式が一般的。 - ソレ以外の WebAPI は、
client_id/client_secretの基本認証や
bearer token を使用。
補足(なぜ Bearer トークンなら不要なのか): 最後の一文が要点で、
CSRF が成立するのは「ブラウザが自動で送る資格情報」を使う場合だけである。
認証方式 自動送信されるか CSRF 対策 Cookie(セッション) される 必要 Basic 認証 される(ブラウザが記憶していれば) 必要 Authorization: Bearerされない(JS が明示的に付ける) 不要 SPA で JWTを
localStorageに置き
ヘッダで送る構成が CSRF に強いのはこのためである
(ただし XSS には弱くなるというトレードオフがある)。逆に「SPA だから安全」ではなく、
Cookie 認証を使う SPA では CSRF 対策が必要である。
案件毎に CSRF(XSRF) 対策のポリシーを持って対応する必要がある。
- GET が通れば即、warning になるので診断ツールの誤検知が多い。
- CSRF(XSRF) になっても実際に問題が起きるかどうかはアプリの作りによる。
一般的に、足がつかない、
- 匿名アクセス可能なサイトか、
- フリーメールサービスのアドレスでサインアップ可能なサイト
が多いと考える。
- 攻撃方法の特定
- 匿名アクセスが可能なサイトの場合、誰でも攻撃可能。
- 会員制サイトの場合、そのサイトを利用可能な会員でないと、
攻撃方法を見い出せない。
- 攻撃方法が解れば、攻撃自体は誰でも出来る。
- しかし、最近は、SameSite属性の件の対策もあり、
同一サイトでないと POST での攻撃も、し難くなって来ている。
補足(SameSite で状況が大きく変わった): 2020年以降、
Chrome の既定がSameSite=Laxになり、
CSRF の大部分が構造的に防がれるようになった。
SameSiteクロスサイトの POST で Cookie が送られるか Strict送られない Lax(現在の既定)送られない(GET のトップレベル遷移のみ許可) None; Secure送られる ただし、これだけに依存してはならない。
- 古いブラウザは
SameSiteを解釈しないSameSite=Noneが必要な構成(form_post、
埋め込み iframe)では効かない- サブドメインは "same-site" 扱い(
evil.example.com→www.example.comは防げない)多層防御として、トークン方式は引き続き実装すべきである。
- セッション ID を CSRF トークンに使うべきでない。
補足(理由): CSRF トークンは HTML 内に出力されるため、
- XSS があれば読み取られる
- キャッシュや Referer から漏れうる
という経路がある。ここにセッション ID そのものを置くと、
CSRF の穴が即セッション ハイジャックに直結してしまう。セッション ID とは別の乱数を生成し、
サーバー側でセッションと紐づけて検証するのが正しい。
ASP.NET Coreの Antiforgery は既定でこの実装である。
補足(Core での書き方): ASP.NET Coreでは
既定で有効になっている部分が多い。
対象 既定の挙動 Razor の <form>タグ ヘルパー自動的に hidden の Antiforgery トークンを出力 [ValidateAntiForgeryToken]個別に付与 [AutoValidateAntiforgeryToken]GET/HEAD/OPTIONS/TRACE 以外を自動検証(推奨) [IgnoreAntiforgeryToken]個別に除外 builder.Services.AddControllersWithViews(options => options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));全体に適用してから、必要な箇所だけ除外する方が
付け忘れによる漏れが起きないため安全である。SPA + Cookie 認証の場合は、
IAntiforgeryからトークンを取得し、
Cookie に載せて JS がヘッダ(X-CSRF-TOKEN)で送り返す構成にする。
-
クロスサイト・リクエストフォージェリ(CSRF)対策(ASP.NET,C#,VB.NET編)
https://www.websec-room.com/2013/03/06/473 -
ASP.NET Core MVC で追加されたAutoValidateAntiforgeryToken属性が便利 - 時が癒す
http://mrgchr.hatenablog.com/entry/2016/11/16/000000 -
脆弱性対策のポイント(
OTR_VulnerabilityCountermeasurePoints.md)
- ASP.NET Core で防ぐクロスサイト リクエスト フォージェリ (XSRF/CSRF) 攻撃
https://learn.microsoft.com/aspnet/core/security/anti-request-forgery
Tags: 移行, テスト, セキュリティ, ASP.NET
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。