Open5

WebAPIのCSRF対策

shimakaze_softshimakaze_soft

そもそもCSRFとは何かについての細かい話は言及しません。

以下に詳しく載っています。

http://gihyo.jp/dev/serial/01/javascript-security/0003

簡単に言えば、ユーザーを攻撃者が罠サイトにアクセスさせて、APIサーバーに対する意図しないリクエストを送信させることです。
そのユーザーがサービスにログイン済みで、セッションIDをクッキーに保存していた場合、その情報がAPIサーバーに送信されることになります。

そして、そのリクエストを受け取ったAPIサーバーは「認証済みのユーザーからのリクエスト」であるため、ユーザーが意図していなかったとしても、そのリクエストは正当なリクエストとして処理され、退会や決済、SNSへの不適切な投稿などといったユーザーが意図しない操作が行われてしまいます。

shimakaze_softshimakaze_soft

CSRFトークンによる対策

王道とも呼べる対策方法。

一番始めにWebページを取得した際にHTMLの中にトークンが含まれていたりする。
そのトークンをjsで頑張って取り出したりして、それをAPIへのリクエストの際に送信します。
DjangoとかRuby on Railsとか比較的フルスタックフレームワーク系には標準でついていたりする機能です。

この方法であれば「CSRFトークンが来た所 = 罠サイトではない所」として正規のリクエストとして扱う方法です。(正確には違うけど。。)

SPAの場合はどうするのか

ただし、この方法は最近流行りのSPAとやらではフロントエンド、バックエンドが独立しているのが一般的であるため難しい問題です。
そもそもトークンをどうやってSPAが動くブラウザに渡すのか。

shimakaze_softshimakaze_soft

CookieにSameSite属性を付与する

以下のURLが一番わかりやすい

https://blog.isystk.com/system_develop/security/csrf/643/

ただし、以下のリンクに詳細があるが、SameStite属性を付与しても以下のように防げないCSRFはある。(よくよく考えればPOSTリクエストをするのに、Cookieにセッション情報とか付与とかしていなければそれはそうだろうとも言える)

*「防げるCSRF」とはセッションが存在しているサイト
*「防げないCSRF」とはセッションを利用していないサイト

https://blog.motikan2010.com/entry/2019/02/02/CookieのSameSite属性で「防げるCSRF」と「防げないCSRF」