結論(Mixed Contentがない)
Mixed Contentがないとは、HTTPSで配信されているページが、スクリプト・スタイルシート・画像・iframeなどのサブリソースを暗号化されないhttp://で読み込んでいない状態です。HTTPとHTTPSが混在すると、そのリソースが経路上で盗聴・改ざんされるおそれがあり、特にスクリプトやCSSを差し替えられるとページ全体を攻撃者に制御されます。現在のブラウザはスクリプトやiframeの混在をブロックするため、表示不具合の原因にもなります。
この記事のポイント
- 画像・動画・音声の混在はブラウザがHTTPSへ自動昇格し、スクリプト・CSS・iframe・fetch等はブロックされます。
- a要素のリンクやrel=canonical・alternate・dns-prefetchなど、取得を伴わない参照はMixed Contentに当たりません。
- 根本対策はHTML内のURLをhttps://やルート相対に直すことで、CSPのupgrade-insecure-requestsは移行期間の補助策です。
- 診断はトップページのHTMLを解析し、HTTP参照が0件で○、upgrade-insecure-requestsありなら△、なしなら×(重み4)です。
- 下層ページやJavaScriptが生成するURL、外部CSS内のurl()は診断対象外のため、主要ページは手動でも確認します。
| 診断項目名 | Mixed Contentがない |
|---|---|
| 項目ID | html.mixed-content |
| 分類 | HTML・JavaScript・外部資産 |
| 重大度・配点の重み | 重要(high) 重み 4 |
| 関連する標準・ガイドライン | W3C Mixed Content(Editor's Draft)/OWASP ASVS 5.0.0 V12.2.1(Level 1:クライアントと外部向けHTTPサービス間の通信はすべてTLSで行い、非暗号化通信へフォールバックしない)/CSP upgrade-insecure-requests(W3C Upgrade Insecure Requests)/CWE-319(Cleartext Transmission of Sensitive Information) |
Mixed Contentがないとは(混在コンテンツの意味)
Mixed Contentがないとは、HTTPSで配信されているページ(トップページ)のHTMLの中に、http:// で読み込まれるサブリソース(スクリプト、スタイルシート、画像、iframe、動画・音声など)が含まれていない状態です。
<!-- Mixed Content になる例 -->
<script src="http://maps.example.com/api.js"></script>
<!-- 修正後 -->
<script src="https://maps.example.com/api.js"></script>
HTTPSのページが一部のリソースを暗号化されないHTTPで取得する状態を Mixed Content(混在コンテンツ) と呼びます。MDNは、安全に読み込まれたページがHTTPなどの安全でないプロトコルでリソースを取得すると、そのリソースが盗聴・改ざんされる可能性があり危険だと説明しています。特にスクリプトやスタイルシートが差し替えられると、ページ全体を攻撃者が制御できてしまいます。
現在のブラウザは、画像・動画・音声の混在は自動的にHTTPSへ昇格し、スクリプト・CSS・iframeなどの混在はブロックします。そのため混在コンテンツは「安全でない」だけでなく、「画像が表示されない」「デザインが崩れる」「地図や動画が出ない」といった表示不具合の原因にもなります。
Mixed Contentの種類とブラウザの動作
昇格可能なコンテンツとブロック対象
W3C Mixed Content 仕様とMDNは、混在コンテンツを2種類に分けています。
| 種類 | 例 | 現在のブラウザの動作 |
|---|---|---|
| 昇格可能(upgradeable) | <img src>、<audio src>、<video src>、<source>(動画・音声)、CSSの背景画像 | HTTPSへ自動昇格して取得。HTTPSで取得できなければ失敗 |
| ブロック対象(blockable) | <script src>、<link rel="stylesheet">、<iframe src>、<object>、fetch()/XHR、Webフォント、srcset や <picture> を使う画像 | 読み込みをブロック |
仕様上、IPアドレスで指定されたホストへのリクエストは自動昇格の対象外です。また、W3C仕様は「upgrade-insecure-requests ディレクティブは、ブロック対象のコンテンツも昇格できるため不要にはならない」と説明しています。
Mixed Contentに当たらないもの
- HTTPページからHTTPのリソースを読む場合:混在の問題はHTTPS(安全なコンテキスト)のページだけで生じます。ページ自体がHTTPならページ全体が平文であり、「HTTPSで配信されている」の問題として扱います。
- リソースの取得を伴わないリンク:
<a href="http://…">(リンク先への遷移)、<link rel="canonical">、<link rel="alternate">、<link rel="dns-prefetch">などはブラウザがリソースとして取得しないため、混在コンテンツにはなりません。canonicalのHTTPS化は「canonicalが安全なURLを指している」で評価します。
upgrade-insecure-requestsの働き
CSPの upgrade-insecure-requests ディレクティブを指定すると、ブラウザはそのページ内のHTTPのURL(ブロック対象を含む)をHTTPSに置き換えて取得します。MDNによると、meta要素のCSPでも有効です。ただし、第三者サイトへのリンクによる遷移は昇格されず、HSTSの代わりにはなりません。また、昇格先のサーバーがHTTPSに対応していなければ読み込みは失敗します。HTMLのURL自体をHTTPSに直すのが根本対策です。
Mixed Contentについてよくある誤解
- 「ブラウザが自動で直すので問題ない」:昇格されるのは一部の種類だけで、スクリプト・CSS・iframeはブロックされ機能が壊れます。また、古いブラウザや一部の組み込みブラウザでは保護されません。
- 「外部サイトの画像だから責任外」:自治体ページに埋め込んだ時点で、そのページの安全性の一部です。
- 「プロトコル相対URL(
//example.com/x.js)なら安全」:HTTPSページではHTTPSで取得されますが、意図を明確にするためhttps://で書くことが推奨されます。
Mixed Contentがないの診断基準(セキュリティAIチェッカー)
取得方法
トップページ(転送後の最終応答)のHTML本文(約2MBまで)を正規表現で解析します。下層ページは対象外です。
判定の対象とする記述
- 要素:
script、img、iframe、frame、audio、video、source、track、input(画像ボタン)、object、embed、link - 属性:
src、href、data、poster(引用符なしの値も含む)、および引用符で囲まれたsrcset内の候補URL link要素は、relがリソースの取得を伴うもの(stylesheet、icon、shortcut icon、apple-touch-icon、apple-touch-icon-precomposed、mask-icon、preload、modulepreload、prefetch、manifest)だけを対象とし、canonical・alternate・dns-prefetch・preconnectなどは除外します。- 値が
http://で始まる記述を「取得を伴うHTTP参照」として数えます。属性名は独立した名前として一致するものだけを見るため、data-src・data-href・data-srcsetのようなdata-*属性は数えません。
判定条件
| 判定 | 条件 | 得点への影響 |
|---|---|---|
| 対象外(na) | 最終URLがHTTP(ページ自体が平文) | 得点計算から除外 |
| ○ 問題なし(pass) | HTTPSページで、取得を伴うHTTP参照が0件 | 重み4 × 1.00 |
| △ 要確認(warn) | HTTP参照があるが、レスポンスヘッダーまたはmeta要素のCSPに upgrade-insecure-requests がある | 重み4 × 0.45 |
| × 要改善(fail) | HTTP参照があり、upgrade-insecure-requests も無い | 重み4 × 0 |
根拠欄には検出件数を表示します。upgrade-insecure-requests がある場合は、ブラウザがHTTPSへ昇格して取得する旨を付記します(昇格先がHTTPS非対応なら表示不具合になるため、△の要確認としています)。
診断の限界
- 属性値に
<や>を含むタグ、遅延読み込み用のdata-src等に書かれ後でスクリプトがsrcへ移すURL、引用符なしのsrcset、JavaScriptが実行時に生成するURL、外部CSSファイル内のurl(http://…)、インラインstyle属性の背景画像は検出しません。 - 下層ページ(お知らせ記事など)の混在は対象外です。CMSの記事本文に古い
http://の画像URLが残っていることが多いため、主要ページは手動確認を推奨します。
自治体サイトでの判定例
| HTMLの記述 | 判定 |
|---|---|
<img src="https://www.city.example.lg.jp/img/top.jpg"> のみ | ○ |
<link rel="canonical" href="http://www.city.example.lg.jp/"> | ○(取得を伴わないため対象外。canonicalは別項目) |
<script src="http://maps.example.com/api.js"> | × |
<img src="http://…"> があり、CSPに upgrade-insecure-requests | △ |
| サイトがHTTPのみで配信 | 対象外 |
Mixed Contentがあるとどんなリスクがあるか
- スクリプト改ざんによるページ乗っ取り:経路上の攻撃者(不正な無線LANアクセスポイント等)がHTTPのJavaScriptを差し替えると、フォーム入力の窃取、偽の案内表示、別サイトへの誘導など、ページ全体を操作できます。ブロックされないブラウザ環境ではこれが現実の脅威になります。
- 画像・動画の差し替え:避難所の地図や案内画像が改ざんされると、誤った情報が住民に伝わります。
- 閲覧内容の推測:HTTPで送られる画像リクエストのURLやCookie(Secure属性が無いもの)から、閲覧しているページが第三者に分かることがあります(CWE-319)。Cookie側の対策は「CookieのSecure属性」を参照してください。
- 表示不具合と信頼低下:ブロックによりデザイン崩れや地図・動画の非表示が起き、ブラウザのアドレスバーに「保護されていない通信」等の警告が表示されるなど、公式サイトとしての信頼を損ないます。
Mixed Contentの直し方(URLのhttps化・Apache・nginx・IIS・Next.js)
1. HTMLのURLをhttpsへ置き換える(根本対策)
# 公開ディレクトリ内のhttp参照を洗い出す
grep -rnoE '(src|href|data|poster|srcset)=["'"'"']?http://[^"'"'"' >]+' /var/www/html --include='*.html' | head
- 自サイトのリソースはルート相対(
/img/top.jpg)またはhttps://にします。 - 外部サービス(地図、動画、SNS埋め込み、アクセス解析)は、提供元が案内するHTTPS版の埋め込みコードに差し替えます。HTTPSに対応していないサービスは利用を見直します。
- CMSでは、記事データベース内の
http://自サイト/を一括置換する機能(WordPressの場合はWP-CLIのwp search-replaceなど)を、バックアップ取得後に使います。
2. 移行期間の補助策:upgrade-insecure-requests
Apache(.htaccess):
<IfModule mod_headers.c>
Header always set Content-Security-Policy "upgrade-insecure-requests"
</IfModule>
既にCSPを設定している場合は、別ヘッダーを追加せず既存のポリシーにディレクティブを追記します(Header always set で上書きすると既存のCSPが消えます)。
nginx:
add_header Content-Security-Policy "upgrade-insecure-requests" always;
IIS(web.config):
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Content-Security-Policy" value="upgrade-insecure-requests" />
</customHeaders>
</httpProtocol>
</system.webServer>
Next.js(next.config.ts):
const nextConfig = {
async headers() {
return [{ source: "/(.*)", headers: [{ key: "Content-Security-Policy", value: "upgrade-insecure-requests" }] }];
},
};
export default nextConfig;
HTMLのmeta要素でも指定できます。
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
3. 確認方法と注意点
- ブラウザの開発者ツールのコンソールに「Mixed Content」の警告・ブロックが出ていないかを、主要ページで確認します。
- 次のコマンドで残存を確認します。
curl -s https://www.city.example.lg.jp/ | grep -oE '(src|href)="http://[^"]+"'
upgrade-insecure-requestsは、昇格先がHTTPS非対応だと読み込みが失敗します。適用前に、外部リソースがHTTPSで取得できるかを確認してください。- HTTPS化そのもの、HTTP→HTTPSの恒久リダイレクト(「HTTPからHTTPSへ転送」)、HSTS(「HSTSが設定されている」)と合わせて対応してください。CSPの許可リストに
http:の配信元が残っていないかは「CSPでHTTP配信元を許可していない」で確認します。
よくある質問(FAQ)
Mixed Contentとは何ですか?
HTTPSで配信されているページが、一部のリソースを暗号化されないHTTPで取得している状態を指し、混在コンテンツとも呼びます。取得したリソースが盗聴・改ざんされる可能性があり、MDNも危険だと説明しています。
ブラウザが自動でHTTPSに直してくれるなら、対応は不要ですか?
不要ではありません。自動昇格されるのは画像・動画・音声など一部だけで、スクリプト・CSS・iframeはブロックされて機能が壊れます。昇格先がHTTPSに対応していなければ読み込みも失敗し、古いブラウザや一部の組み込みブラウザでは保護されません。
Mixed Contentはどうやって見つけられますか?
ブラウザの開発者ツールのコンソールに表示される「Mixed Content」の警告・ブロックを主要ページで確認します。curlでHTMLを取得してsrcやhrefがhttp://で始まる箇所を検索する方法や、公開ディレクトリをgrepで洗い出す方法もあります。
upgrade-insecure-requestsを設定すれば解決しますか?
移行期間の補助策としては有効で、ブラウザはページ内のHTTPのURLをHTTPSに置き換えて取得します。ただし昇格先がHTTPS非対応なら読み込みに失敗し、第三者サイトへのリンク遷移は昇格されずHSTSの代わりにもなりません。この診断でも△にとどまり、HTMLのURLを直すのが根本対策です。
プロトコル相対URL(//example.com/x.js)は問題ありませんか?
HTTPSのページではHTTPSで取得されるためMixed Contentにはなりませんが、意図を明確にするためhttps://で書くことが推奨されます。
HTTPで配信しているサイトはどう判定されますか?
ページ自体がHTTPならページ全体が平文で、混在の問題はHTTPSのページだけで生じるため「対象外」とします。HTTPS化は「HTTPSで配信されている」の項目で評価します。
この項目を含む127項目を、URLを入れるだけで無料診断します。