結論(CORS設定)
CORS設定の診断では、Access-Control-Allow-Origin に * や null を返していないか、それらを Access-Control-Allow-Credentials: true と組み合わせていないか、リクエストのOriginをそのまま反射していないか、動的CORSで Vary: Origin を返しているか、プリフライトの許可範囲が適切かを確かめます。CORSは同一オリジンポリシーを緩める仕組みで、認可やCSRF対策の代わりにはなりません。
CORS(クロスオリジン設定)の診断項目一覧(5項目)
他サイトからのデータ読み取りを許す範囲(CORS)が広すぎないかを確認します。各項目名から、意味・診断基準・リスク・具体的な対策を解説したページへ移動できます。
| No. | 診断項目 | 重大度 | 概要 |
|---|---|---|---|
| 29 | 危険なCORSワイルドカードがない | high | 危険なCORSワイルドカードがないとは、Access-Control-Allow-Originに * や null を安易に返していない状態です。 |
| 30 | CORSの認証情報設定に矛盾がない | high | CORSの認証情報設定に矛盾がないとは、Access-Control-Allow-Credentials: true を * や null と組み合わせていない状態です。 |
| 99 | 任意Originを反射しない | high | 任意Originを反射しないとは、CORSでリクエストのOriginをそのままAccess-Control-Allow-Originに返さないことです。 |
| 100 | 動的CORSでVary: Originを返す | medium | 動的CORSでVary: Originを返すとは、Originに応じてAccess-Control-Allow-Originを変えるAPIで、キャッシュの使い回しを防ぐ設定です。 |
| 125 | CORSプリフライトの許可範囲 | high | CORSプリフライトの許可範囲は、OPTIONSによる事前確認への応答で、Access-Control-Allow-Origin・Methods・Headersをどこまで許すかの… |
CORS設定の診断とは
CORS設定の診断は、他のサイト(別のオリジン)で動くJavaScriptが、自サイトの応答をどこまで読み取れるようになっているかを確かめるものです。セキュリティ診断127項目のうち、CORS(クロスオリジン設定)に関する5項目がこの分類に入ります。
ブラウザには、あるオリジンのページが別のオリジンの応答を勝手に読めないようにする「同一オリジンポリシー」があります。CORSは、この制限をサーバーの明示的な許可がある場合に限って緩める仕組みです。許可の範囲は、主にレスポンスヘッダー Access-Control-Allow-Origin(ACAO)で示し、Cookieなどの認証情報を伴う読み取りまで許す場合は Access-Control-Allow-Credentials: true を併せて返します。
CORSで問題になるのは、「許可を出しすぎる」ことです。全サイトからの読み取りを許す * や、誰でも作り出せる null を返したり、リクエストのOriginをそのまま書き戻したりすると、攻撃者のページから応答を読まれる余地が生まれます。とくに認証情報の許可と組み合わさると、利用者が攻撃者のページを開いただけで、ログイン中の利用者の権限で取得したデータを読み取られる、実際に悪用可能な構成になります。
一方で、CORSは「応答を読めるか」の制御であり、要求の送信自体は止めません。CORSを正しく設定してもCSRF対策にはならず、ACAOを付けなくても curl などからは読めるため、APIの認可の代わりにもなりません。CORSの診断は、あくまで「ブラウザ経由で外部サイトに応答を読ませていないか」を見るものです。
5項目の全体像(3つのグループ)
この分類の5項目は、大きく3つのグループに分けて考えると整理しやすくなります。
| グループ | 診断項目 | 確認する内容 |
|---|---|---|
| 許可するオリジンの範囲 | 「危険なCORSワイルドカードがない」、「任意Originを反射しない」 | ACAOが * や null になっていないか、リクエストのOriginを検証せずにそのまま書き戻していないか |
| 認証情報とプリフライト | 「CORSの認証情報設定に矛盾がない」、「CORSプリフライトの許可範囲」 | Access-Control-Allow-Credentials: true を * や null と組み合わせていないか、OPTIONSのプリフライトに対して許可するオリジン・メソッド・ヘッダーが広すぎないか |
| キャッシュとの整合 | 「動的CORSでVary: Originを返す」 | Originによって ACAO を切り替える場合に、キャッシュが別のオリジン向けの応答を使い回さないよう Vary: Origin を返しているか |
セキュリティAIチェッカーは、トップページの応答に加えて、/api/ などのAPI候補にも、実在しない検証用のOriginを付けて要求を送り、反射が起きないかを確かめます。Access-Control-Allow-Origin がない応答は他オリジンからの読み取りを許していないことを意味するため、認証情報の設定やプリフライトの項目は対象外(na)として採点から除外されます。
優先して確認すべき項目
この分類に重大度「最重要(critical)」の項目はありませんが、5項目のうち4項目が「重要(high)」です。悪用のしやすさの順に確認します。
- 任意Originを反射しない:反射では ACAO が常に要求元と一致する値になり、ワイルドカード(*)に対するブラウザ側の安全装置をすり抜けます。Allow-Credentials: true と組み合わさると、罠ページを開いただけで氏名・申請履歴・CSRFトークンなどを読み取られます。
- CORSの認証情報設定に矛盾がない:null + credentials は、サンドボックス化したiframeの null オリジンから実際に読み取れる構成です。* + credentials はブラウザが拒否する仕様違反の設定ですが、「動かないから」と反射方式へ書き換えて本当に危険になりがちです。この組み合わせは × 要改善と判定されます。
- CORSプリフライトの許可範囲:未許可のOriginでプリフライトを送り、反射や認証情報付きの *・null を×、null のみを△と判定します。
- 危険なCORSワイルドカードがない:トップページの応答が * または null なら △ 要確認です。* は公開データには正当な設定のため、同じ設定がAPIやログイン後画面に及んでいないかの確認が中心になります。
「中(medium)」の「動的CORSでVary: Originを返す」は、それ自体が攻撃を許すものではありませんが、付けないとブラウザやCDNが応答を使い回し、正規の連携先でCORSエラーが起きたり、許可していないオリジンへ許可ヘッダー付きの応答が渡ったりします。
直すときの進め方と注意点
CORSの設定は、「どのパスで、どのオリジンに、認証情報付きの読み取りを許すのか」を決めることから始めます。次の順で進めると、正規の連携を壊さずに絞り込めます。
- CORSが必要なパスを限定する:Webサーバーや CDN 全体に一括で * を設定していると、公開データ以外にも許可が及びます。CORSは公開データ用のパスだけに限定します。
- 固定の許可リストと完全一致で照合する:機密APIでは、許可リストと完全一致したオリジンだけに ACAO を返します。前方一致・後方一致、ドットをエスケープしない正規表現、null の許可は典型的な誤りです。example.lg.jp を含むかどうかで判定すると、example.lg.jp.attacker.example のようなドメインを許してしまいます。
- 認証情報の許可は最小限にする:Access-Control-Allow-Credentials: true は、許可リストと一致したオリジンにだけ返します。false は有効な値ではないため、不要な場合はヘッダー自体を出力しません。
- Vary: Origin を付ける:Originによって応答が変わる場合は、許可しないOriginに ACAO を出さない実装でも Vary: Origin が必要です。ACAO が * や固定のオリジンなら Vary は不要です。Apacheでは既存の Vary: Accept-Encoding を消さないよう、Header always merge を使います。
- プリフライトの許可も絞る:Access-Control-Allow-Methods と Access-Control-Allow-Headers は必要最小限にし、明示的にサポートするメソッドだけを許可します。
- CORSに頼らない対策を併せて行う:状態を変える処理には、CSRFトークンやSameSite Cookieが別途必要です。
自治体・公共機関のサイトで特に注意すること
自治体や公共機関は、オープンデータや地図タイル、公開CSVのように誰でも取得してよいデータを配信する一方で、庁内向けの情報や申請・照会系のシステムも運用しています。CORSの設定では、この2つを分けて考えることが大切です。
- オープンデータAPIや公開ファイルでは、認証情報なしの * は正当で推奨される設定です。応答に機密情報を含めないことが前提になります。
- ファイアウォールや送信元IPだけで保護された庁内向け情報は、Cookieを使わない保護のため、* や反射を許していると、職員のブラウザを踏み台に外部サイトから読まれる可能性があります。
- トークンをクエリ文字列で渡すAPIも、Cookieなしで機密データが読めてしまいます。
- マイページや申請履歴など、ログイン中の利用者の情報を返すAPIでは、反射や null と認証情報の組み合わせが、個人データの読み取りに直結します。
多くの自治体公式サイトのトップページにはCORSのヘッダーがなく、この分類の一部の項目は対象外になります。ただし、公式サイトとは別に調達したAPIや申請システムで設定されている場合があるため、外部と連携しているシステムごとに、許可しているオリジンと認証情報の扱いを一覧にして確認しておくと安心です。
よくある質問(FAQ)
CORS設定の診断項目は、どの順番で直せばよいですか?
まず、Originの反射と、* や null を Access-Control-Allow-Credentials: true と組み合わせた設定(いずれも重要)をなくします。次に、プリフライトの許可範囲と、* や null のワイルドカードが公開データ以外に及んでいないかを確認し、最後に動的CORSで Vary: Origin を返しているかを整えます。
CORS設定で Access-Control-Allow-Origin: * はすべて危険ですか?
すべてではありません。オープンデータAPIや公開CSVなど誰でも取得してよい公開ファイルでは、認証情報なしの * は正当な設定です。ただし、IPやネットワーク位置で保護された庁内向け情報や、URLにトークンを含むAPIでは、外部サイトから応答を読まれる原因になります。
CORS設定で Origin: null を許可してもよいですか?
許可すべきではありません。null はサンドボックス化したiframeやローカルファイルから送られる値で、攻撃者も作り出せるため、null 許可は事実上「誰でも許可」と同じです。認証情報の許可と組み合わさると、ログイン中の利用者のデータを読み取られます。
CORS設定を正しくすればCSRFも防げますか?
防げません。CORSは応答を読めるかどうかの制御で、要求の送信自体は止めません。状態を変える処理には、CSRFトークンやSameSite Cookieが別途必要です。また、curl などからは読めるため、APIの認可の代わりにもなりません。
トップページにCORSのヘッダーがない場合、CORS設定の診断はどうなりますか?
認証情報の設定やプリフライトの項目は、Access-Control-Allow-Origin がなければ対象外(na)として得点の分母から除外されます。他オリジンからの読み取りを許していないことを意味するためで、多くの自治体公式サイトのトップページはこの状態です。
CORS設定の5項目はまとめて確認できますか?
セキュリティAIチェッカーにURLを入力すると、この5項目を含む127項目を公開情報から自動で診断し、項目ごとの判定と改善の優先順位を表示します。