攻撃から学ぶCSRF対策

#はじめに
WEBエンジニアとして成長するために、セキュリティ対策は避けては通れない道ですよね。

僕も含め **「なんとなく知ってる」** という方は多いのではないでしょうか。

大切なWEBサイトを守るためにも、WEBエンジニアとしての基礎を固める為にも、しっかりと学んで一緒にレベルアップしていきましょう。

また、本記事の内容は様々な文献をもとに自身で調べ、試したものをまとめています。
至らぬ点や、間違いがありましたら、コメントにてご指摘をお願いします。

他にも様々な攻撃手法についてまとめているので、興味のある方は読んでみてください。
[攻撃から学ぶXSS対策](https://qiita.com/risto24/items/70625bb6631ad12266d3)
[攻撃から学ぶSQLインジェクション対策](https://qiita.com/risto24/items/0354a902faeb442cddcc)

#CSRFって何？
CSRF（Cross-Site Request Forgery）とは、サービスの利用者に意図しないHTTPリクエストを送信させ、意図しない処理を実行させる攻撃手法です。

これだけでは分からないので、攻撃の流れをまとめてみましょう。

その前に、CSRFにおいて大きな鍵となる **Cookie** について簡単に説明します。（すでに既知の方は飛ばしてください）

##Cookieとは
Cookie（クッキー）とはWebサイトへのアクセスを行なったユーザーが、再訪した際に同一人物であることを認識する為に、ブラウザに残しておくデータのことです。

この情報を使うことによって **過去にWebサイトを訪れたユーザーかどうかを識別** することができます。
ECサイトなどでショッピングカートに入れて、一度ブラウザを閉じたとしても、再度アクセスするとカートに商品が残っているのは、このCookieという情報で同一人物であると認識しているからです。

#CSRF攻撃の流れ
では実際に例を元に攻撃手法を学んでみましょう。
###前提条件
過去にSNSやECサイトにログインして、ブラウザにCookieが残っているユーザーがターゲットです。

###攻撃の流れ（SNS投稿 ver.）
1. 攻撃者は罠となるWEBサイトを用意します。
2. 掲示板などでURLをクリックさせ、罠となるWEBサイトへ誘導します。
3. 罠となるWEBサイトをターゲットが閲覧すると、悪意のあるコードを実行して、過去にログインしたことのあるSNSに、投稿リクエストを送信します。
4. SNSを運用するサーバは、過去にログインしたことのあるユーザーが、投稿リクエストを送ってきたと誤認識します。
5. ターゲットの知らない間にSNSに悪意のある投稿がされてしまいます。

###攻撃の流れ（パスワードリセット ver.）
1. 攻撃者は罠となるWEBサイトを用意します。
2. 掲示板などでURLをクリックさせ、罠となるWEBサイトへ誘導します。
3. 罠となるWEBサイトをターゲットが閲覧すると、悪意のあるコードを実行して、過去にログインしたことのあるECサイトに、攻撃者が用意したパスワードにリセットをするようにリクエストを送ります。
4. ECサイトを運用するサーバは、過去にログインしたことのあるユーザーが、パスワードリセットのリクエストを送ってきたと誤認識します。
5. ターゲットの知らない間にパスワードが変更されてしまいます。

#CSRFの怖さ
このように、CSRFはログイン済みのユーザに意図しない操作を強制的に実行させてしまう攻撃であるといえます。

近年は、年齢を問わず多くの人がオンラインバンキングやSNSなどの複数のインターネットサービスを当たり前のように利用していることから、多額の金銭的被害を受ける可能性があります。

そのほかにも、SNS投稿を通じて他人への誹謗中傷や、殺害予告などといった悪意のある攻撃も考えられます。

**CSRFは被害をすぐに自覚することが難しい攻撃手法です。**

そのため、被害者が気が付くのは、すでに何らかのアクションが起こされた後になり、誤認逮捕といった信頼回復が難しい被害へと発展することも多くあります。

#CSRFの対策
CSRFは、過去にログイン済みサイトのCookieを持つユーザに攻撃者が用意したWEBサイトから悪意のあるリクエストを行う攻撃手法です。

このタイプの攻撃を防ぐには **リクエストの送信元を確認する仕組みが必要です。**

僕たちWEB開発者ができる対策を挙げてみましょう。
対策の細かい設定は別に調べてもらった方がいいと思うので簡略的に説明します。

###セッションCookieには常にSameSite属性を使用する
SameSite属性は [draft-west-first-party-cookies-07 – Same-site Cookies](https://tools.ietf.org/html/draft-west-first-party-cookies-07) という仕様で新しく追加されたCookieの属性で、Cookieをより安全なものにするために追加されました。

SameSite属性とは、サーバが最初にCookieを発行する際に`SameSite属性`を指定しておけば、ドメインを跨いだ（クロスドメイン）リクエストにそのクッキーをセットさせないことが可能になります。

###リファラーヘッダーまたはオリジンを確認する
リファラーヘッダーとは、遷移元のウェブページのアドレスが含まれているヘッダー情報になります。
これにより、サーバはリクエストがどこから来たかを識別し、分析・ログ・キャッシュの最適化などに利用することができます。

ちなみに豆知識ですが、 `Referer header` の `Referer` というスペルは誤字であり、正式な英単語は `Referrer` です。
これは、HTTPが策定された時に、ヘッダ名を間違ったスペルで書いてしまった歴史的経緯から続いており、現在もこのスペルで運用されています。

###ユーザーインタラクションベースの保護を実装する
再認証（パスワード以上）、ワンタイムトークン、CAPTCHAなどのユーザーが特定の操作を行なったとき、システムがその操作に応じた反応を返す処理を実装しましょう。
これにより、CSRFからの強力な防御を可能にすることができます。

#まとめ
XSSと同様にCSRFも、開発者にとっては大きな脅威となる攻撃方法です。
攻撃方法を知り、防御策を徹底することで、ユーザを犯罪に巻き込む危険性を最小限に抑えることができます。

サービスを開発・運営する上で、責任と自覚をもち、対処していきたいと改めて感じました。

また、今回も様々な文献を参考にさせて頂きました。
詳しく知りたい方は、是非読んでみてください。

###参考文献
[JavaScript Security Issues and Best Practices](https://blog.bitsrc.io/javascript-security-issues-and-best-practices-37e78df4dce4)
[csrfの仕組みと対策を解説](https://www.techdevicetv.com/ch_cybersecurity/52/)
[意図しない処理が実行されるCSRFとは？概要と対策](https://tech-blog.rakus.co.jp/entry/2017/09/21/113626)
[HTTP クッキーをより安全にする SameSite 属性について](https://laboradian.com/same-site-cookies/)
[Referer](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Referer#:~:text=Referer%20%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%98%E3%83%83%E3%83%80%E3%83%BC%E3%81%AB%E3%81%AF,%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)
[HTTPリファラ](https://ja.wikipedia.org/wiki/HTTP%E3%83%AA%E3%83%95%E3%82%A1%E3%83%A9#%E3%83%AA%E3%83%95%E3%82%A1%E3%83%A9%E3%81%AE%E9%9A%A0%E8%94%BD)