APIセキュリティの「玄関」を守る:CORS設定の基本とワイルドカードの罠
こんにちは。セキュリティの現場で日々、巧妙な攻撃と戦っているエンジニアです。
今日は、Webアプリケーション開発で避けては通れない「CORS(Cross-Origin Resource Sharing)」についてお話しします。「また難しそうな横文字が出てきたな……」と身構える必要はありません。CORSは、あなたの作ったAPIという「家」を守るための、非常にシンプルで大切な「防犯ルール」に過ぎないのです。
一歩ずつ、防犯の考え方から一緒に紐解いていきましょう。
—
1. CORSって何?:家の鍵と「信頼できる訪問者リスト」
想像してみてください。あなたは自分の家(Webサーバー)に、大切な宝物(APIで扱うデータ)を置いています。
本来、Webブラウザのセキュリティ機能(同一生成元ポリシー)は、あなたの家の中に「知らない人(他のドメインからのアクセス)は絶対に入れない!」という非常に厳しい鉄の扉を設置しています。しかし、Webの世界では「このサイトからは、あのお店のAPIを使わせたい」というケースがどうしても出てきますよね。
そこで登場するのが「CORS」です。「この人なら入れてもいいよ」という信頼できる訪問者リストを扉に貼り付けておく、これがCORSの正体です。
2. やってはいけない「ワイルドカード」設定
ここで一番やってはいけないのが、何でも屋さんのような設定です。
# 絶対にやめてください!
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: * と書くと、「世界中の誰でもウェルカム!」という意味になります。これは、家の玄関に「鍵は開いています。泥棒さん、どうぞご自由に入ってください」と看板を掲げるようなもの。
攻撃者はこれを見逃しません。悪意のあるサイトを訪問したユーザーのブラウザを操り、あなたのAPIに対して勝手にリクエストを送らせ、認証情報(クッキーなど)を盗み出そうとします。ワイルドカード(*)は、セキュリティにおける最大級の敗北だと心得てください。
3. 安全な設定:具体的なリストを作ろう
安全な運用のためには、許可する相手を具体的に指定するのが鉄則です。例えば、あなたの運営する https://my-app.com だけを許可したい場合は、以下のように記述します。
サーバー側の設定例 (PHPの場合):
<?php
// 許可するオリジンを固定する
$allowed_origin = "https://my-app.com";
// リクエスト元がリストに含まれているかチェック
if (isset($_SERVER['HTTP_ORIGIN']) && $_SERVER['HTTP_ORIGIN'] === $allowed_origin) {
header("Access-Control-Allow-Origin: " . $allowed_origin);
// 認証情報(クッキー等)を許可する場合はこれが必要
header("Access-Control-Allow-Credentials: true");
}
?>
こうすることで、「この家は特定の知人しか入れない」という厳重なガードが成立します。
4. 「プリフライトリクエスト」という事前の確認
CORSには、もう一つ「プリフライトリクエスト」という仕組みがあります。
いきなりAPIを叩かせるのではなく、ブラウザが本番のリクエストを送る前に、「ねえ、この操作をしても怒らない?」とサーバーに挨拶(OPTIONSメソッドでの通信)を送る仕組みです。
- ブラウザ: 「
POSTメソッドで、Content-Type: application/jsonを送りたいんだけど、いい?」 - サーバー: 「ああ、その条件なら許可してあげるよ」
このやり取りがスムーズに行われるよう、サーバー側で OPTIONS メソッドへの応答を適切に準備しておく必要があります。
5. まとめ:今日からできる防犯対策
最後に、今日からできることを整理しましょう。
1. ワイルドカードは封印する: * を使わず、信頼できるドメイン名だけを許可リストに載せましょう。
2. Access-Control-Allow-Credentials は慎重に: 認証情報を含むリクエストを許可する場合、必ずオリジンを固定してください。
3. プリフライトを理解する: ブラウザが送る OPTIONS リクエストに対して、適切に「許可」のヘッダーを返す準備をしましょう。
セキュリティは「完璧」を目指すよりも、「攻撃者の手間を増やすこと」が大切です。こうして一つずつ、防犯の意識をコードに落とし込んでいけば、あなたのAPIは格段に強固になります。
難しく考えず、まずは自分のAPIが「誰を招き入れているのか?」を確認することから始めてみてくださいね。応援しています!
コメント