【入門編】カスタムHTTPヘッダーを用いたCSRF防御の限界と有効性 – アプリケーションセキュリティ & 安全な開発防御ガイド

こんにちは。現場の最前線でコードとログに向き合い続けているセキュリティエンジニアです。

今日は「カスタムHTTPヘッダーを使ったCSRF(クロスサイト・リクエスト・フォージェリ)対策」という、一見スマートに見えるけど実はちょっとした「落とし穴」があるテーマについて、一緒に紐解いていきましょう。

セキュリティの世界は、時に家の防犯とそっくりです。まずはその感覚から掴んでいきましょうか。

—

1. CSRFってなに?:家の鍵と「なりすまし」の話

CSRFとは、簡単に言うと「あなたが普段使っているブラウザを悪用して、勝手に操作を代行させる攻撃」のことです。

想像してみてください。あなたは自分の家の玄関(Webアプリのログイン状態)を開けっ放しにして、ちょっとコンビニへ行きました。その隙に、泥棒があなたの家の裏口から勝手に入り込み、あなたの名前で「この家を売ります」という書類に勝手にハンコを押させる……。これがCSRFの恐ろしいところです。

攻撃者は、あなたがログインしていることを悪用して、「あなたのブラウザ」から「サーバーへ」勝手に命令を送らせるわけです。

—

2. カスタムヘッダー(X-Requested-With)による防御の仕組み

この攻撃を防ぐために、昔からよく使われているのが「カスタムHTTPヘッダー」をチェックする方法です。

例えば、Ajax(JavaScriptを使った非同期通信)でリクエストを送る際に、X-Requested-With: XMLHttpRequest という、「これはJavaScriptから送られたリクエストですよ」という名札(ヘッダー)を付ける手法です。

サーバー側は、「このリクエストに名札が付いていないなら、怪しいから拒否しよう!」と判断します。

なぜこれが有効なのか?

実は、ブラウザには「HTMLの標準機能(

タグなど)では、リクエストに勝手なカスタムヘッダーを付けられない」というルールがあるからです。

つまり、攻撃者が悪意のあるサイトからあなたのブラウザを操ろうとしても、そのリクエストに「名札(カスタムヘッダー)」を付けることができず、サーバーで弾かれる……という仕組みです。

—

3. 「CORS」のプリフライトで防壁を突破される?

ここで少しレベルアップした話をします。もし、あなたのサイトのCORS(クロスオリジンリソース共有)設定がガバガバだったらどうなるでしょうか?

ブラウザは、JavaScriptから複雑なリクエストを送る際、まずサーバーに「プリフライトリクエスト(確認の挨拶)」を送ります。
「ねえ、このヘッダー付けて送ってもいい?」とサーバーに聞きに行くんですね。

もし、あなたのサーバーが「OK!どんなヘッダーでも許可するよ!」という設定(Access-Control-Allow-Headers: など)になっていたら、攻撃者は堂々とカスタムヘッダーを付けてリクエストを送れてしまうんです。

「家の鍵をかけたはずなのに、泥棒が『この鍵、開けてもいいよね?』と聞いたら、あなたが『いいよ!』と答えてしまった」状態です。これが、カスタムヘッダー対策の限界点です。

—

4. 実務で守りを固めるためのコード例

では、どうすればいいのか。一番確実なのは、「ワンタイムトークン(CSRFトークン)」を併用することです。ヘッダーだけに頼らず、サーバーから発行した「使い捨ての合言葉」をリクエストに含めてもらうのが、今のセキュリティの正解です。

以下に、Flask(Python)での防御の概念を示します。

from flask import request, abort

@app.route(‘/transfer-money’, methods=[‘POST’])
def transfer_money():
# 1. カスタムヘッダーの確認(第一の防壁)
if request.headers.get(‘X-Requested-With’) != ‘XMLHttpRequest’:
abort(403) # 名札がない!拒否!

# 2. CSRFトークンの確認(本丸の防壁)
# リクエストボディやヘッダーに含まれるトークンを検証する
token = request.headers.get(‘X-CSRF-Token’)
if not verify_token(token):
abort(403) # 合言葉が違う!泥棒だ!

return “送金成功!”

—

5. まとめ:防犯は「多層」で考える

今回のポイントを整理しましょう。

  • カスタムヘッダーは便利だが、それだけでは万能ではない。
  • CORS設定を適当にすると、防御の穴になる。
  • 結局のところ、CSRFトークンなど「サーバーが発行した合言葉」を組み合わせるのが一番安心。

セキュリティは「これさえやっておけば絶対大丈夫」という魔法の杖はありません。家の玄関には鍵をかけ、窓には補助錠を付け、防犯カメラを回す。Web開発もこれと同じです。

まずは、自分のアプリケーションのCORS設定を見直すところから始めてみませんか?「誰に対しても許可する」設定になっていないか確認するだけで、あなたのアプリの安全性はグッと高まりますよ。

一歩ずつ、安全な開発の階段を登っていきましょう!応援しています。

コメント

タイトルとURLをコピーしました