Djangoでアプリケーション開発をしていてフォームを設置するときに、 {% csrf token %} というおまじないみたいなものを使いますが、こいつってそもそも何者なんでしょうか?
今回はエンジニア歴が浅い方や、非エンジニアの方向けに、このcsrf tokenが「何者なのか」というのを、ざっくりと分かりやすく書いていきます!
#そもそもCSRFって何?
csrf token を理解する前にまずは「csrf」がそもそも何かを少し説明します!
csrfを訳してみると
「サイト間を横断する(Cross Site)リクエストの偽造(Request Forgery)」
となり、
__悪意のあるサイトが、被害者となるユーザのフリをして、別のサイトにリクエストを飛ばして、そこで悪さをする__といった内容になります。
これだけだと分かりづらいですね汗
なのでまずはcsrfによるトラブル例をご紹介して、
それぞれのステップで何が起きているかを説明していきます!
注:この記事ではcsrfの概念の理解のために厳密な表現を避けております。あくまでcsrfが全く分からない!という方が少しでも理解いただけるように書かせていただきます...!
例)
1. Twitterにログイン状態のユーザーが、悪意のあるウェブサイトに遷移する
2. 遷移先の悪意のあるウェブサイト内に(ユーザーが思わず押してしまうような)リンクが用意されていて、ユーザーが実際にクリックしてしまう
3. そのリンクはTwitter内のツイート投稿処理のURLと紐づいており、ユーザーに覚えのないツイートが勝手に投稿されてしまう
1. Twitterにログイン状態のユーザーが、悪意のあるウェブサイトに遷移する。
csrfが行われる際には、「ユーザー」「ユーザーがログイン中のサイト(この例ではTwitter)」「悪意のあるウェブサイト」の3つの登場人物が出てきます。
この「1」のプロセスで大事なポイントは、__ユーザーが何かしらのサイトにログイン中である__という点です。
サイトにログインすると、ユーザーが使用しているブラウザのセッションには「今Twitterにこのアカウントでログイン中だよ~」というような情報が保存されます。
そしてこの「セッションに保存されたログイン情報」というのは、別のタブで別の作業をし始めようとも、ログアウトしない限りはずっとブラウザに保存されます。
ここが味噌となります。
2.遷移先の悪意のあるウェブサイト内に(ユーザーが思わず押してしまうような)リンクが用意されていて、ユーザーが実際にクリックしてしまう
そして、その後「悪意のあるウェブサイト」に、何かしらのサイトにログイン状態のユーザーが遷移してくると、悪意のあるウェブサイトによる攻撃が始まります。
ここで今更ですが、悪意のあるウェブサイトの目的を、今回の例では「誰かのTwitterアカウントから[公共の場に爆弾を仕掛けた]という旨のデマ情報を流したい」とかにしておきましょう。
また、この悪意のあるウェブサイトは、遷移してきたユーザーに対して
「あなたのスマホがウイルスに感染しているかもしれません!下記のリンクをクリックしてスキャンしてください!」
と脅してくるサイトだとしましょうか。
ネットになれていないユーザーだと不安を煽られて思わず押してしまいそうですが、
この「下記のリンク」にはある細工が仕掛けられていて...
3. そのリンクはTwitter内のツイート投稿処理のURLと紐づいており、ユーザーに覚えのないツイートが勝手に投稿されてしまう
既にWebアプリケーションの開発経験がある方からすると理解しやすい部分かと思いますが、
ネット上でツイートを投稿したり、そのツイートを編集したり、投稿した過去のツイートを削除したり...という処理を行う際には、画面だけ見ていると分かりませんが、それぞれにURLが割り振られているんです。
つまり何が言いたいかというと、__処理のためのURLと、必要な情報(ツイートに書きたいことなど)を用意すれば、Twitter以外の外部のサイトからでもツイートが可能である__ということなのです。
そしてこの悪意のあるウェブサイトは、ツイート投稿を行うために割り振られたURLと、投稿内容([公共の場に爆弾を仕掛けた]という旨)を用意しておいて、
「下記のリンクをクリックしてスキャンしてください!」という文言で示されたリンクに埋め込むことで、
__ユーザーがそのリンクをクリックした時に、リンクをクリックしたユーザー自身のアカウントからそのツイートを作成させることが可能となる__のです。
これが「csrfとは何か」に対しての説明になります!
#本題!「csrf token」とは何者?
それでは本題に入っていきます!
csrf tokenがあることで、このcsrfを防げるのですが、いったいどうやって機能しているのでしょうか?
まず、csrf tokenがフォームに設置されることで、
ログインしたタイミングで、「このユーザーはログインしてるよ!」という情報と共に、ユーザーのブラウザのセッションに対csrf用の特別な鍵が渡されます。
ここで注目すべきポイントは、__ユーザーのブラウザにはその特別な鍵が存在する__ものの、__悪意のあるウェブサイトはその鍵を持っていない__という点です。
これを利用して、csrf tokenを設置しているサイト側では、
__ツイートを送信しようとしている人物がその鍵を持っていない場合はツイートを許可しないということが可能となる__のです。
なので、前述のような方法で悪意のあるウェブサイトが偽造ツイートを作成しようとしても、
__悪意のあるウェブサイト自体はログインしていない(ログインしたのはユーザー自身だから)ために鍵を持っておらず、偽造ツイートが作成できない__ようになっています。
(つまり直接ツイートを投稿する人物がその鍵を持っていないと投稿できない、という意味になります。)
以上が「csrf token」の説明となります!
#まとめ
一言でまとめるとcsrfとは、「被害者ユーザーがログイン中のサイトで、好き勝手いろいろやる(語彙力...)」ような攻撃方法のことで、
csrf tokenはそれを防いでくれる仕組みとなっています。
既に記載したように、csrf tokenの概念理解のために厳密な表現とは違う部分もあったかとは思いますが、
この記事をきっかけに「なんとなくcsrfってそういうことなのね!ちょっと自分でも調べてみよう!」と思ってくださった方がいたら嬉しいです!
また、この記事への感想や内容への指摘など、お気軽にコメントを頂けますと幸いです!
最後までご拝読いただきありがとうございました!
追記
こちらの記事を書いた後に見つけたのですが、
CSRFについてさらに詳しく知りたい方がいましたら、こちらのサイトがかなり参考になると思います!
ハンズオン形式で実際にCSRFを再現することで理解を深められる内容になっております。