なぜあなたのWebサイトは「なりすまし」を許してしまうのか?CSRF対策の基本を丁寧に紐解く
こんにちは。セキュリティの現場で日々、防御の最前線に立っている者です。
今日は、開発現場でつい後回しにされがちな、しかし一度やられると致命傷になりかねない「CSRF(クロスサイト・リクエスト・フォージェリ)」についてお話しします。
「聞いたことはあるけれど、結局どう防げばいいの?」「フレームワークが守ってくれるって聞くけど、それだけで安心?」そんな疑問を、身近な防犯に例えて一緒に紐解いていきましょう。
—
CSRF(なりすまし)って、どんな攻撃?
CSRFをひとことで言うと、「泥棒があなたのフリをして勝手に合鍵を作り、家の中を荒らすこと」です。
想像してみてください。あなたは今、銀行のWebサイトにログインしています。その状態で、たまたま開いた別の悪意ある掲示板のリンクをクリックしてしまったとします。すると、裏側で銀行サイトに対して「この口座から犯人の口座へ100万円送金せよ」という命令が自動的に送信されてしまう……これがCSRFの恐ろしさです。
なぜこんなことが起きるのか? それはWebブラウザが「あなたが今そのサイトにログインしている」という情報を、勝手に送ってしまう癖を持っているからです。
泥棒を防ぐ「ワンタイムパス」という仕組み
この攻撃を防ぐための最も強力な武器が、「CSRFトークン」です。
これは例えるなら、「家に入るたびに発行される、使い捨ての合鍵」のようなものです。
1. サイト側が、フォームを表示するたびに「今回はこれを使ってね」という秘密の文字列(トークン)を発行します。
2. ユーザーが「送信」ボタンを押すとき、そのトークンも一緒に送ります。
3. サーバー側は、「送られてきたトークンは、さっき私が発行したものと一致するか?」を確認します。
もし、泥棒があなたのフリをして勝手に命令を送ろうとしても、泥棒は「今発行されたばかりの使い捨ての合鍵」を知りません。だから、サーバーは「この命令は本物じゃないな」と見抜くことができるのです。
—
主要フレームワークの「守り」を確認しよう
最近のモダンなフレームワーク(Spring Security, Django, Railsなど)は、この仕組みを標準で備えています。ありがたいことに、基本的には「ON」の状態になっていますが、「何がどう動いているか」を知っておくことがエンジニアとしての第一歩です。
Djangoの場合(設定の確認)
Djangoは非常に親切で、デフォルトでミドルウェアが有効になっています。
settings.py
MIDDLEWARE = [
# これがCSRFを防ぐ門番です。無効化してはいけません。
‘django.middleware.csrf.CsrfViewMiddleware’,
]
フォームにはこれを入れるだけでOKです。
Spring Securityの場合
Spring Securityも強力です。設定クラスで防御を有効にします。
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// デフォルトでCSRF対策は有効です。
// 明示的に無効にする必要がない限り、そのままにしておきましょう。
http.csrf(csrf -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
);
return http.build();
}
}
—
「とりあえず動くから」で終わらせないための3つの注意点
フレームワークが守ってくれるとはいえ、以下のポイントだけは現場で必ず確認してください。
1. GETリクエストで状態を変えない
検索画面など、データを取得するだけの「GET」リクエストは安全だと思われがちです。しかし、GETで「/delete?id=1」のような処理を書くと、CSRFの標的になりやすいです。「変更」は必ず「POST」で行うのが鉄則です。
2. SameSite属性の活用
Cookieの属性に SameSite=Lax や Strict を設定しましょう。「別のサイトからのリクエストには、このCookieを渡さない」というブラウザの強力な防壁になります。最近はブラウザのデフォルト設定も強くなっていますが、明示的に指定するのがプロの仕事です。
3. APIサーバーの場合はどうする?
Web画面(HTML)ではなく、フロントエンド(React/Vueなど)とJSONでやり取りするAPIサーバーの場合、CSRFトークンの扱いが変わります。この場合は「カスタムヘッダー」を使った認証や、JWTの運用など、より専門的な設計が必要になります。
—
最後に:セキュリティは「疑うこと」から始まる
セキュリティ対策に「これだけで完璧」という魔法はありません。しかし、フレームワークが用意してくれている標準機能を正しく理解し、「どこに鍵をかけ、誰を通すべきか」を意識するだけで、あなたのサイトの安全性は劇的に向上します。
「動いているから大丈夫」と放置せず、一度自分の書いたコードがどうやって攻撃を防いでいるのか、ログを眺めたり設定を見直したりしてみてください。それが、優秀なエンジニアへの近道です。
一歩ずつ、強固なシステムを一緒に作っていきましょう!
コメント