クロスサイトリクエストフォージェリ(CSRF)とは?
クロスサイトリクエストフォージェリ(CSRF)とはWebサービスの脆弱性を利用した攻撃です。
簡単に説明すると、クロスサイトリクエストフォージェリ(CSRF)とは、攻撃者が別のユーザーになりすまして不正にリクエストを送信することで、ECサイトやオンラインバンクで勝手に決済されるといった被害が発生する攻撃手段になります。
クロスサイトスクリプティング(XSS)と 並んで被害件数が非常に多い攻撃であり、各種Webサービスの開発者は、必ず知っておかないといけない攻撃の一つと言えると思います。
もう少し詳しく解説
上記だけだと具体的な話が一切なく、分かったような分からないような状態になると思うので、もう少し開発者の方など向けに詳しく解説していこうと思います。
クロスサイトスクリプティングを理解するにはまずCookieについての理解が必要になります。
Cookieとはブラウザが保存している小さなデータ群のことで、ログイン情報やセッション識別子といったものを保存しています。
Cookieにあるデータはそれぞれのリクエストごとにサーバーに送信されます。サーバー側はこのCookieにある情報を元に、現在ログインしているのかどうかということや、ログインしているユーザーはどのユーザーなのかということを判定しています。
クロスサイトリクエストフォージェリの多くはこのCookie情報を悪用することで実行されます。
Cookieはブラウザで保存されており、タブ・ウィンドウ間でも共有されます。そこで攻撃者は悪意のあるサイトを作成し、そのサイトを表示した際にCookie情報を読み取り、そのCookie情報を使用してリクエストを送ることで、本人になりすましてリクエストを送ることができるというわけです。
「ECサイトにログインした状態で、攻撃者の作成したページをわざわざ開くことなんてないんじゃないか?」と思うかもしれませんが、攻撃者もバカではありません。ありとあらゆる手を使って、気づかないように悪意のあるサイトにページ遷移させてきます。
そこで次にこのクロスサイトリクエストフォージェリ(CSRF)の例を見てみましょう。
クロスサイトリクエストフォージェリ(CSRF)の例
①フィッシングメールからECサイトの不正注文が行われる
クロスサイトリクエストフォージェリは他の攻撃と組み合わせて使われることが多く、この例ではフィッシングメールを使用した例になります。
フィッシングメールとは大手サイトに成り済ましたメールを不特定多数に送信し、メール内リンクから悪質なウェブサイトにページ遷移させる攻撃です。
まず攻撃者はクロスサイトリクエストフォージェリの脆弱性が発見されたECサイトを装い、利用者にメールを送信します。
(例えばメールアドレスの確認など、違和感ない内容であることも多いです)
そこでメール内のリンクを押し悪質なサイトに遷移してしまった場合、攻撃者のスクリプトがブラウザのCookie情報を利用してECサイトに特定の商品の注文のリクエストが送信されます。
この時、ブラウザのCookieにそのECサイトの認証情報が残っていた場合、注文が正常に完了してしまい、利用者は知らないうちに知らない商品を購入してしまうということです。
たしかにこの攻撃は下記条件が揃っていないと成立しないので、確率としては低いかもしれません。
- ECサイトに上記攻撃を実行できる脆弱性が存在する
- フィッシングメールのリンクをクリックしてしまう
- ECサイトの認証情報がブラウザに残っている状態で、そのブラウザでフィッシングメールのURLが開く
ただ攻撃者は一度悪質なサイトを作って終えば、あとは大量にメールを送信するだけなので、攻撃自体は非常に簡単になってしまうところが、この攻撃の恐ろしいところかもしれません。
②SNSのプロフィールのリンクを開くとSNSアカウントが乗っ取られる
次にSNSなどの個人がプロフィールを登録して情報を発信できるようなサービスで起こる攻撃です。
SNSのプロフィールに「もっと詳しいプロフィールはこちら」のように記載して悪質なウェブサイトのURLをクリックさせます。
そのURL先で不正なスクリプトが動かすことでクロスサイトリクエストフォージェリ攻撃が成功してしまいます。
ここで取得したcookieの認証情報から直接ログインすることはできないのですが、「ログインした状態をなりすましてリクエストを送る」ことはできるので、パスワード再設定機能のリクエストなどを送ることで、最終的に完全にアカウントが乗っ取られるといったことも考えられます。
先ほどのフィッシングメールとは違い、ほぼ確実にログインした状態でURLを開くことになるので、攻撃の成功確率は①のものと比べるとかなり高いかもしれません。
開発者はもちろんのことですが、サービス利用者も「知らないドメインのURLにはアクセスしない」等、日頃から気を付ける必要がありそうです。
クロスサイトリクエストフォージェリ(CSRF)の対策について
上記にあるように、クロスサイトリクエストフォージェリはログイン機能のあるWebサービスなら常に気をつける必要のある攻撃になります。これらは一体どのように対応すれば良いのでしょうか。
①CSRFトークンを利用する
クロスサイトリクエストフォージェリの最も一般的な対策と言われるのは、各セッションや各フォームごとにそれぞれトークン(CSRFトークン)を発行することです。
各セッションや各フォームごとに発行し、リクエスト送信時にそのトークン情報を含めることで、サーバー側ではそのトークンを元に正しいリクエストかどうか判定できるという訳です。
ウェブ開発者が使用する現代の多くのフレームワークでは、上記機能が簡単に(もしくは自動で)実装することができます。
例えばPHPの代表的なフレームワークであるLaravelではフォーム実装時に必ず@csrf
と書かないとエラーになりますが、これは@csrf
と書くことで自動でトークンを作成してフォームに埋め込むことができるという訳です。
LaravelだけでなくDjango・Ruby on Railsといった有名なWebフレームワークではだいたいの場合は簡単に対策することができますが、特にフレームワークを使用せず開発する場合は必ず注意する必要があります。
②Cookieのフラグを適切なものに設定する
Apache等のウェブサーバーの設定でCookieに関する設定を行うことができます。
その中でも下記設定はこのクロスサイトスクリプティングに関わらず有用な設定になります。
1. HttpOnlyフラグの設定
CookieにHttpOnlyフラグを設定することで、JavasciprtからCookieにアクセスすることができなくなります。
名前的にHttpsでアクセスできなくなりそうですが、そういうわけではないので、積極的に設定するようにしましょう。
2. Secureフラグの設定
Secureフラグを設定することで、HTTPS通信の場合のみCookieが送信されるようになります。
今時まともなサイトは基本的に全て常時SSL化していると思うので、積極的に設定して良いと思います。
3. SameSiteフラグの設定
SameSiteフラグとはドメインの異なるサイト間におけるCookieの設定を表すフラグです。
設定できるフラグは3つ存在し
- Strict・・・別ドメインの場合、Cookieを送信しない
- Lax・・・別ドメインの場合、GETリクエストのみCookieを送信する
- None・・・ドメイン関係なく、Cookieを送信する
の3つになります。
Strictにすると外部サイトのリンクからサイトに遷移した場合に必ずログアウトされてしまうなど、利用者にとって不便な状況を生んでしまう設定でもあります。
システム開発者はWebサービスに応じて適切なフラグを設定する必要があります。
コメント