HTTPS化後の混在コンテンツを見つけて直す手順
証明書は入れた。トップページには鍵のマークも出る。なのに古い記事を開くと「保護されていない」と表示され、埋め込んでいたウィジェットが消えている。
原因の多くは、ページの中に残った http:// の読み込みです。ページ本体はHTTPSで届いていても、画像やスクリプトをHTTPで取りに行けば、そのページは安全とは扱われません。直す先は証明書ではなく、HTML・テンプレート・CMSの本文データのほうです。
順番は決まっています。見つける、仕分ける、直す、取りこぼしを拾う。最後に一括の安全網をかける。この順で進めれば、作業が漏れません。
何が「混ざって」いるのか
web.dev の説明では、最初のHTMLが安全なHTTPS接続で読み込まれているのに、画像・動画・スタイルシート・スクリプトなどの他の資源が安全でないHTTP接続で読み込まれているページを、混在コンテンツ(Mixed Content)があるページと呼びます。1つのページにHTTPとHTTPSの中身が混ざっている、という意味です。
危険の大きさは、混ざっているものの種類で変わります。web.dev は2種類に分けています。
| 種類 | 主な例 | 公式の説明にあるリスク | ブラウザの扱い |
|---|---|---|---|
| 受動的な混在(passive) | 画像・動画・音声 | 画像の差し替えや、読み込みから閲覧ページを追跡されることがある | 多くのブラウザがアドレスバーで「安全でない」と示す。Chrome は場合により自動でHTTPSに切り替え、安全な版がなければ読み込まない |
| 能動的な混在(active) | スクリプト・スタイルシート・iframe など | 書き換えられるとページ全体、ときにはサイト全体を乗っ取られる | 多くのブラウザが既定でブロックする(挙動はブラウザやバージョンで異なる) |
ここから実務の手がかりが2つ出てきます。
一つは、症状の違いです。画像が混ざっているだけなら、ページは表示されたまま警告だけが出ることがあります。スクリプトやスタイルが混ざっていると、ブロックされて機能や見た目が壊れることがあります。「ウィジェットが消えた」「レイアウトが崩れた」は、能動的な混在を疑う合図です。
もう一つは、画像だから放置してよいわけではない点です。web.dev は、受動的な混在でも、画像の差し替えや利用者の追跡といったリスクは残ると書いています。さらに、受動的な混在を読み込まない方向へブラウザが変わりつつあるとも述べています。今は表示されている画像も、いずれ表示されなくなるかもしれません。
手順1〜2: まず見つける
手順1: 代表ページを Chrome で開いて警告を読む
Chrome でHTTPSのページを開くと、混在コンテンツはJavaScriptコンソールにエラーや警告として出ます。web.dev によると、Chrome は混在コンテンツを検出したときや受動的な混在を自動で切り替えたときに、DevTools の「Issues」タブへ詳しいメッセージを記録し、安全でない資源ごとに制限の状態を一覧にします。
見つけた http:// のURLは、見つけたページと一緒に表へ控えておきます。web.dev もこのリストづくりを勧めています。
注意点が1つあります。この警告は、いま開いているページの分しか出ません。別ページへ移るとコンソールは消えます。つまり、この方法だけで全ページを調べるには、1ページずつ開くしかありません。
そこで、最初は「型」ごとに代表ページを選んで開くのが効率的です。トップ、カテゴリ一覧、新しい記事、HTTPS化より前に書いた古い記事、問い合わせフォーム。テンプレートが違うページを1枚ずつ見れば、テンプレート由来の混在はおおむね拾えます。
手順2: ソースとCMSの本文を http:// で検索する
次は、全ページを開かずに探す方法です。web.dev は、ソースコードを http:// で検索し、HTTPのURLを属性に持つタグを探す方法を挙げています。
ここで止まりやすいのが、リンク(<a> タグ)の扱いです。web.dev によると、<a> の href にある http:// は、多くの場合混在コンテンツの問題になりません。リンクはクリックで別ページへ移るだけで、今のページに資源を読み込まないからです。ただし例外があります。画像ギャラリーのスクリプトの中には、<a> の href が指すHTTPの資源を、ページ上の拡大表示(ライトボックス)に読み込むものがあり、これは混在コンテンツになります。
CMSを使っているなら、テンプレートだけでなく本文データも検索します。web.dev は、CMSでは公開時に安全でないURLが入り込むことがあり、たとえば画像が相対パスではなく完全なURLで入る例を挙げています。HTTPS化より前に書いた記事の画像が、http:// 付きの完全なURLで本文に保存されたまま、というのはこのパターンです。
手順3〜4: 仕分けて直す
手順3: 1件ずつ「HTTPSで取れるか」を確かめる
見つけたURLを、直し方で仕分けます。判断の起点は、その資源がHTTPSで取得できるかどうかです。
web.dev の手順はこうです。コンソールに「HTTPからHTTPSへ自動で切り替えた」というメッセージが出ている資源は、コードの http:// を https:// に書き換えて問題ありません。メッセージが出ていない資源は、アドレスバーで http:// を https:// に変えて開いてみれば、安全に取得できるか確かめられます。
HTTPSで取得できない資源には、web.dev が3つの選択肢を挙げています。
- 別の配信元から読み込む(HTTPSで配っている提供元があれば)
- 法的に許される場合は、ダウンロードして自社サイトに置く
- その資源をサイトから外す
判断を表にまとめると、次のようになります。
| 見つかったもの | HTTPSで取れるか | 直し方 |
|---|---|---|
| 自社ドメインの画像・CSS・JS | 取れる | ルート相対パス(/images/logo.png の形)か https:// に書き換える |
| 外部の画像・スクリプト(CDN・ウィジェット) | 取れる | https:// に書き換える |
| 外部の画像・スクリプト | 取れない | 別の配信元に替える/許諾があれば自社に置く/外す |
<a href="http://..."> の通常リンク | 問わない | 多くの場合は対象外。ライトボックスで資源を読み込むものだけ直す |
| 他社サイトへの通常リンク | 問わない | 下の「エッジケース」を参照 |
手順4: 書き換えて、同じページで消えたか確かめる
自社の資源は、相対パスで書くのが扱いやすい方法です。Search Console ヘルプは、サイト内のURLを特定のプロトコルに依存させないよう求め、相対パスか、プロトコルを省いた //example.com/something.js の形を挙げています。ページ間のリンクについても、プロトコル相対(//example.com で始まる)か、ホスト相対(/jquery.js のようにパスだけで始まる)にするよう書いています。
<!-- 直す前 -->
<img src="http://www.example.com/wp-content/uploads/2019/05/flow.png">
<script src="http://widget.example.net/embed.js"></script>
<!-- 直した後 -->
<img src="/wp-content/uploads/2019/05/flow.png">
<script src="https://widget.example.net/embed.js"></script>
書き換えたら終わり、ではありません。web.dev は、直したあとで最初にエラーを見つけたページを開き直し、エラーが出なくなったことを確かめるよう書いています。手順1で作った表に「確認済み」の列を足して、1行ずつ埋めていくと漏れません。
CMSの本文データを一括置換する場合は、手作業ではなくスクリプトで書き換えます。Search Console ヘルプは、間違いを避けるためにリンクの更新は手ではなくスクリプトで行い、内容がデータベースにあるならデータベースの開発用の複製で試し、品質確認を通ってから本番に反映するよう書いています。置換の前に、本番データのバックアップも取っておくと戻せます。
架空の例で通してみる
ここまでの手順を、架空の会社ブログで1回通します。HTTPS化して1か月。トップは問題ないのに、2019年の記事を開くとアドレスバーに警告が出て、記事下の資料請求ウィジェットが表示されません。
手順1で、その記事を Chrome で開いて Issues タブを見ます。並んだのは3件でした。
- 本文の図版
http://www.example.com/wp-content/uploads/2019/05/flow.png(自動でHTTPSに切り替えたというメッセージあり) - 資料請求ウィジェット
http://widget.example.net/embed.js(ブロック) - サイドバーのバナー画像
http://ads.example.org/banner.gif(切り替え不可で読み込まれず)
手順2でテンプレートを検索すると、サイドバーのバナーはテンプレート由来でした。図版は本文データに完全なURLで入っており、2020年以前の記事のほぼすべてに同じ形で残っていました。
手順3で仕分けます。
1件めの図版は、さきほどの表の1行めに当たります。自動切り替えのメッセージが出ているので、HTTPSで取れることは確定です。本文データを一括でルート相対パスに置換すれば、古い記事すべてがまとめて直ります。
2件めのウィジェットは、表の2行めか3行めのどちらかです。https://widget.example.net/embed.js を開くと中身が返ってきました。2行めです。テンプレートの1か所を書き換えるだけで済みます。ウィジェットが消えていた理由も、ここで説明がつきます。スクリプトは能動的な混在なので、ブラウザにブロックされていたのです。
3件めのバナーは、HTTPSで開くと接続できませんでした。表の3行めです。提供元にHTTPS版の有無を問い合わせ、なければバナー自体を外します。
手順4で3件を直し、同じ記事を開き直します。Issues タブが空になり、アドレスバーの警告も消えました。ただしこれは、代表ページで見えた分だけです。開いていないページに、別の http:// が残っているかもしれません。そこで次の手順に進みます。
手順5〜6: 取りこぼしを拾い、安全網をかける
手順5: CSPの報告専用モードで、まだ残っている混在を集める
1ページずつ開く方法は、小さなサイト向けです。web.dev は、大きなサイトや開発チームが分かれているサイトでは、CSP(Content Security Policy:ページが読み込んでよいものをブラウザ側で制限する設定)を使う方法を挙げています。
報告専用のヘッダーを付けると、ブロックはせずに違反だけを報告させられます。
Content-Security-Policy-Report-Only: default-src https: 'unsafe-inline' 'unsafe-eval'; report-uri https://example.com/reportingEndpoint
web.dev によると、利用者がページを訪れるたびに、ブラウザはポリシー違反の内容をJSON形式で報告先へ送ります。この例では、HTTPで読み込まれた資源があるたびに報告が届き、報告には違反が起きたページのURLと、違反した資源のURLが含まれます。自分で全ページを開かなくても、残りを追えるということです。
ただし限界が2つあります。CSPを理解するブラウザで訪問された場合しか報告されないこと。そして、利用者が訪れたページの分しか報告が来ないこと。アクセスの少ないページは、報告が揃うまで時間がかかることがあります。また、報告用の Content-Security-Policy-Report-Only は <meta> タグでは設定できず、サーバーのレスポンスヘッダーで送る必要があります。
ヘッダーを触れないブログサービスで運用している場合は、web.dev が代わりにサイト巡回ツール(クローラー)で探す方法を挙げています。
手順6: upgrade-insecure-requests は最後の安全網として使う
一括で済ませたくなる設定もあります。CSPの upgrade-insecure-requests を指定すると、ブラウザは安全でないURLを、通信する前にHTTPSへ書き換えて読み込みます。指定はヘッダーでも、<head> 内の <meta> でもできます。
Content-Security-Policy: upgrade-insecure-requests
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
web.dev によると、この指定はブラウザの自動切り替えより広い範囲の読み込みを切り替えようとし、ページ内の <iframe> にも及びます。
ただし、魔法ではありません。資源がHTTPSで取得できなければ、切り替えた読み込みは失敗し、その資源は読み込まれません。先ほどの例のバナー画像は、この設定を入れても表示されないままです。手順3〜4で直す作業は省けない、ということです。手順1〜5で直したうえで、今後うっかり入る http:// への備えとして足すのが、無理のない使い方です。
エッジケースとよくある誤解
他社サイトへのリンクも一括で書き換えてよいか。 Search Console ヘルプは、他のサイトへのリンクには可能ならHTTPSのURLを使うよう勧める一方で、他のサイトへのリンク(そのサイトの資源を読み込むのではなく、移動するだけのリンク)についてはプロトコルを変えないようにとも書いています。相手のサイトがどう運用されているかは、こちらでは制御できないからです。通常のリンクは混在コンテンツの原因にならないので、一括置換の対象は自社ドメインと、読み込んでいる外部資源に絞るのが安全です。他社へのリンクを https:// にしたい場合は、置換に混ぜず、相手のページがHTTPSで開けることを1件ずつ確かめてから変えてください。
古いブラウザでは問題が見えないことがある。 web.dev は、ブラウザの提供元やバージョンによって混在コンテンツの扱いが違い、最悪の場合、古いブラウザはまったくブロックしないと書いています。自分の環境で表示されていても、それは直っている証拠になりません。Issues タブとソース検索で確かめてください。
混在コンテンツを直せば順位が上がるか。 これは、今回の出典からは言えません。Googleは2014年にHTTPSをランキングシグナルとして使い始めると発表しましたが、そのときの説明は、影響は世界のクエリの1%未満で、質の高いコンテンツなどの他のシグナルより重みが小さい、とても軽いシグナルというものでした。混在コンテンツを直す価値は、まず利用者の安全と、ブロックで壊れた表示や機能を元に戻すことにあると考えるのが妥当です。
自己点検リスト
作業が終わったら、次を1つずつ確かめてください。
- テンプレートが違うページを1枚ずつ開き、Issues タブに混在の項目が出ていない
- テンプレートとCMSの本文データを
http://で検索し、読み込み用の属性(画像・スクリプト・CSS・iframe)に残っていない -
<a>のhttp://のうち、ライトボックスで画像を開くものだけは直した - HTTPSで取れない外部資源は、配信元の変更・自社に置く・外すのどれかで処理した
- 直したページを開き直し、警告が消えたことを確かめた
- ヘッダーを触れるなら、
Content-Security-Policy-Report-Onlyで残りの報告を集めている -
upgrade-insecure-requestsは、上の作業を終えたあとの安全網として入れた
鍵マークの警告が消えても、検索側の「代表URL」がまだhttp側を向いていることはあります。その切り分けはSSL化済みなのにHTTPSの警告が出るときの点検手順で扱っています。HTTPS化を含むURL変更をこれから進めるなら、転送の設計はサイト移転でURLが変わるときの301リダイレクト手順とあわせて確認してください。
出典
