なぜ「Bearerトークン」を使うとCSRFが死ぬのか?―現場が誤解しがちな認証の境界線
エンジニア諸君、今日もセキュアなコードを書いているか?
現場でコードレビューをしていると、未だに「API認証にはBearerトークンを使っているから、CSRF対策は不要だよね?」という問いに対して、なぜそう言い切れるのかを論理的に説明できないエンジニアが多い。曖昧な理解は、設計の隙を生む。今日は、その「なぜ」を、攻撃者の視点とブラウザの挙動から徹底的に解剖しよう。
1. そもそもCSRFの「本質」は何か?
CSRF(Cross-Site Request Forgery)の核心は、「ブラウザが勝手にクッキーを送信する」という仕様を悪用することにある。
攻撃者は、被害者がログイン中のWebサイト(例:bank.com)に対して、被害者のブラウザ経由で悪意のあるリクエストを投げさせる。ブラウザは、たとえリクエストの発信源が攻撃者のサイト(evil.com)であっても、bank.com のセッションクッキーを律儀に付与してしまう。サーバー側は「クッキーが正しい=本人だ」と判断し、処理を実行してしまうわけだ。
2. なぜBearerトークンはCSRFを無効化するのか?
ここでBearerトークン(Authorization: Bearer )の出番だ。
ブラウザの仕様として、Authorization ヘッダーは、ブラウザが自動的に付与することはない。JavaScript(XHRやFetch API)を介して、開発者が明示的にヘッダーにセットしない限り、そのリクエストは存在しない。
つまり、攻撃者が evil.com から被害者のブラウザを使ってリクエストを飛ばしても、そこには認証トークンが含まれていない。サーバー側は「認証情報がないリクエスト」として、問答無用で 401 Unauthorized を返す。これが、Bearerトークンが「自動的にCSRF耐性を持つ」とされる理論的背景だ。
3. 実践:攻撃者の視点(PoC)
もし君がクッキーベースで認証を行っているなら、攻撃者は以下のようなシンプルなHTMLだけで、ユーザーの意図しない操作を実行できてしまう。
一方で、Bearerトークン方式を採用している場合、このフォーム送信にはトークンが含まれないため、攻撃は完全に失敗する。
4. セキュアな実装ガイド:フロントエンドから送る方法
では、正しくBearerトークンを使ってAPIを叩くための、最もモダンで安全なJavaScript(Fetch API)の実装例を紹介する。
// セキュアにAPIを呼び出す関数
async function secureApiCall(url, method = ‘GET’, body = null) {
// トークンはローカルストレージやメモリ管理された変数から取得
const token = localStorage.getItem(‘access_token’);
const options = {
method: method,
headers: {
// ここで明示的にヘッダーをセットする。これこそが防御の要。
‘Authorization’: Bearer ${token},
‘Content-Type’: ‘application/json’
},
body: body ? JSON.stringify(body) : null
};
const response = await fetch(url, options);
if (response.status === 401) {
// 認証エラー時のハンドリング(リフレッシュトークン処理などへ繋ぐ)
console.error(‘トークンが無効です’);
}
return response.json();
}
5. 注意!「トークンの保存場所」こそが新たな攻撃対象
「CSRFを防げるからBearerトークンは最強」というのは半分正解で、半分は罠だ。
Bearerトークンは、「誰でも送れる(=窃取されると終わる)」という特性を持つ。もしブラウザの localStorage にトークンを保存している場合、XSS(クロスサイトスクリプティング)攻撃を受けた瞬間に、攻撃者はトークンを盗み出し、君のAPIを自由に叩けるようになる。
現場のエンジニアへの訓示:
1. CSRF対策を過信しない: 認証ヘッダー方式にするなら、セットで必ず「強力なCSP(Content Security Policy)」を導入し、XSSを徹底的に封じ込め。
2. CORS設定の厳格化: Access-Control-Allow-Origin を “ にするなど論外だ。信頼できるドメインのみをホワイトリストで許可すること。
6. まとめ
Bearerトークンを採用すれば、従来のセッションクッキーに依存したCSRF攻撃は防げる。これは事実だ。しかし、セキュリティとは常にトレードオフである。CSRFという脅威を排除した代わりに、我々は「XSSによるトークン窃取」という別の脅威に対し、これまで以上に警戒を強めなければならない。
セキュリティに「これで完璧」はない。あるのは「攻撃コストをいかに高めるか」という戦いだけだ。この知識を武器に、君たちのシステムを盤石なものにしてくれ。
何か不明点があれば、またいつでも聞いてくれ。現場からは以上だ。
コメント