今回はCSRF攻撃についての解釈とじゃあ結局どうすればいいんだってばよというのに対する解決策をまとめます。
もちろん、正確には違う部分もあるかもなのでそこはご愛嬌で🙏
CSRF攻撃って何?
Webアプリケーションではユーザーの実行権限がないとアクセスできないリクエストがあります。
例えば、
- お気に入りにした投稿一覧を取得する
- 商品を購入する
- チャットで会話する
など、これらは誰がやったのかをサーバサイドで識別するのにセッション情報を利用します
CORS(Cross Site Request Forgery)攻撃はこのセッションを利用して実際の利用者になりすまして、意図しないリクエストを実行する攻撃です
よく紹介されている攻撃手順としては
- 利用者に攻撃用のサイトにアクセスさせる
- 攻撃用のサイトで上手いこと利用者の権限で攻撃対象のサイトに(意図しない)リクエストを送る
- 利用者はやった覚えのない操作をしたことになり、被害を受ける
ですね。
ECショップへの攻撃例
ECサイト(Am○zonやR○kutenなど)への攻撃例を図解してみたらこんな感じになると思う
攻撃サイト(Attacker Site)からEC Siteへのリクエスト時に利用者のセッション情報を使うことができたら、アカウントは削除されてしまう。。
そもそもCORS制約で弾かれるのでは?
このリクエスト自体って外部のサイトから実行されているからCORSの制約によって弾かれるよね?だから、気にすることないんじゃねと俺は思ったんだけど
どうやら、CORSで弾くのはXHRやFetch APIなので通常のフォームリクエストは通してしまいます。
なので次のようなフォームでユーザーに実行させるように誘導したら、CSRF攻撃は実行できてしまいます。
1 2 3 4 5 6 7 8 9 |
<!DOCTYPE html> <html> <body> <h2>悪意のあるサイト</h2> <form action="https://ec-site.com/delete-account" method="POST"> <button type="submit">100万円配布キャンペーンに応募する</button> </form> </body> </html> |
Cookieって違うオリジンには渡せないから、そもそも認証通らないのでは?
Cookie自体にも、違うオリジンでもリクエストで渡せるかどうかがSameSiteポリシーに設定されてます
大きく分けて3つあって
- Strict:一番厳しい 厳密に正しいサイト以外からのリクエストにはCookieを送信しない。CSRF攻撃の対策にはなるけど、サイト間の連携など色々な箇所で融通が効かない
- Lax:Strictを少し緩和したバージョン サイト間の遷移(リンクをクリックする)場合ではCookieを送信するが、POSTメソッドやXHRなどによるリソースの読み込みではCookieを送信しない。昨今の標準となっている
- None:どのような場合でもCookieをそうしんする、よほどの理由がない限りは手抜きとしか言いようがない
なので、Laxの場合でもリンククリックさせてGETリクエストではCookieを渡すので完全に防げるわけではないとのNoneの場合は言わずもがな制限なく遅れちゃうので安心はできないです
結局のところ、どうしたらいいの?
大きく2つの対策があると思ってます。
CSRFトークンを使う
これはよく聞くやつですよね
セッションとは別にユーザー自身がそのリクエストを実行したことを証明するトークンです
このCSRFトークンを付けてリクエストを送信して、サーバサイドでそのトークンが正しいユーザーのものだと判別できたらリクエストが正常に処理されます
CookieのSameSiteをStrictやLaxにする
次にはCookieのSameSiteをStrictやLaxにする必要があります。
Strictにすれば、攻撃サイトからのありとあらゆるリクエストではCookieは送信しないですが、他のサイトからログイン状態を保持したままのアクセスができない可能性がでてくるので
場合によっては、アプリケーションの利便性を下げてしまいます。
Laxにすれば、POSTやXHRやFetch APIなどによるアクエスは制限できますが、リンクでのアクエスではCookieを渡すのに留意する必要があります
ただ、フォームリクエストの場合はどのみちCookieは送信するので、上述のCSRFトークンもつけてあげるのが好ましいです
まとめ
今回は、CSRF攻撃についてとその対策について紹介しました
まとめると
- CSRF攻撃は、ユーザーのセッションを使って意図しないリクエストを送る攻撃
- CORSによる制約やCookieのSameSiteでも完璧には防げない
- 対策としてはCSRFトークンを使うのは鉄板
でした、ざっくりとした部分もありますが、しっかりと理解してよりセキュリティのあるアプリケーション開発をしていきましょう!以上です