0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cloudflare における Mixed Content エラーへの対応

Last updated at Posted at 2024-11-13

Mixed Content エラーとは

要は HTTPS ページの中に HTTP が混ざっているとブラウザでエラーが出ます。

エラーを出さないためには、様々なリソースのリンクを HTTPS で統一する必要があります。

混在コンテンツ
ユーザが HTTPS を通じてページにアクセスすると、ユーザとウェブサーバとの接続は TLS で暗号化され、盗聴や中間者攻撃から保護されます。HTTPS のページの中に通常の平文の HTTP で送られてくるコンテンツが含まれている場合、混在コンテンツと呼ばれます。このようなページは部分的にしか暗号化されておらず、盗聴者や中間者攻撃者が暗号化されていないコンテンツにアクセスできてしまいます。つまり、ページは安全ではありません。

混合コンテンツとは?
TLS(SSLも呼ばれます)を使用すると、インターネット通信が暗号化され、より安全なブラウジング体験を提供できます。TLSで暗号化されているサイトはURLに「http://」ではなく「https://」が含まれているため、ユーザーは簡単に識別することができます。ただし、場合によってはHTTPSサイトには平文のHTTPプロトコルを使用して読み込まれるいくつかの要素を含めることもできます。これは「HTTP over HTTPS」とも呼ばれる、混合コンテンツと呼ばれる状態を生み出します。
image.png

混合コンテンツのエラーの修正方法は?
混合コンテンツの修正は非常に単純です。Web開発者は、ページ上のすべてのリソースがHTTPS経由でロードされるようにする必要があります。

Mixed Content エラーへの対応

以下のようなガイドがありますが、Automatic HTTPS Rewrites と Snippets を使った例を確認します。

  • リンク指定時に相対パスを使う(絶対 URL 指定に http を使わない)
  • Automatic HTTPS Rewrites 等を使って httphttps に書き換える

解決方法
一般的なアドバイス
混合コンテンツエラーを解決するには、2つの方法があります。

  1. HTTPまたはHTTPSプロトコルを指定せずに、HTMLソースからすべてのリソースを読み込みます。例えば、http://domain.com/path/to.file の代わりに /domain.com/path/to.file を使用します。
  2. コンテンツ管理システムによっては、HTTPリソースを自動的にHTTPSに書き換えるプラグインがないか確認する。Cloudflareは、Automatic HTTPS Rewritesを介してそのようなサービスを提供しています。

Automatic HTTPS Rewrites

ゾーンごとの設定、または Configuration Rules によって、設定できます。

image.png

image.png

以下のサイトにあるデモ用の iframe を拝借して、動作確認します。

image.png

このような場合には Automatic HTTPS Rewrites を使って httphttps に書き換えることができます。

# Automatic HTTPS Rewrites なし
% curl -s https://example.com/ | grep "iframe src"
<iframe src="http://asp.jcity.co.jp/FORM/?UserID=demo&formid=135" frameborder="0" width="100%" height="600" style="border:1px solid #d4d4d4;"></iframe>
# Automatic HTTPS Rewrites あり
% curl -s https://example.com/ | grep "iframe src"
<iframe src="https://asp.jcity.co.jp/FORM/?UserID=demo&formid=135" frameborder="0" width="100%" height="600" style="border:1px solid #d4d4d4;"></iframe>

Snippets

Snippets なし

ただし、以下のような場合には Automatic HTTPS Rewrites の効果がないため、Snippets が必要なことがあります。

一部のリソースは、サイトがブラウザで読み込まれる際に、JavaScriptやCSSによってHTTP経由で読み込まれます。そのような状況では、混合コンテンツの警告が表示されます。

image.png

例えば、以下のような Server としての Workers と、HTML ファイルを用意することで動作検証ができます。

iframe-mixed-content.html
<html>
  <head>
    <script type="text/javascript">
      function addIframe() {
        var url = "https://return-json.example.com/";
        fetch(url)
          .then(function (data) {
            return data.json();
          })
          .then(function (json) {
            var uri = json.d.ReportLink.Uri;
            console.log(uri);

            var target = document.getElementById("targetDiv");
            var iframe = document.createElement("iframe");
            iframe.style["width"] = "100%";
            iframe.style["height"] = "600";
            iframe.style["border-style"] = "border:1px solid #d4d4d4;";
            iframe.src = uri;
            iframe.frameBorder = 0;

            target.appendChild(iframe);
          });
      }
    </script>
  </head>

  <body>
    <a href="javascript:addIframe()">Test</a>
    <div id="targetDiv"></div>
  </body>
</html>

worker.js (https://return-json.example.com/)
export default {
  async fetch(request) {
    const data = {
      "d": {
        "ReportLink": {
          "Uri": "http://asp.jcity.co.jp/FORM/?UserID=demo&formid=135",
        },
      }
    };

    return Response.json(data);
  },
};

Snippets あり

この場合、以下のような Snippets を設定することでクライアントブラウザ内のスクリプトで取得される iframe.src としての URL を http から https に書き換えることができます。

要件としては Workers でも問題ありませんが、簡易版 Workers である Snippets での設定例を確認します。

snippets.js
export default {
    async fetch(request) {

        const originalResponse = await fetch(request);

        const originalBody = await originalResponse.json();
        const body = JSON.stringify({
            ...originalBody
        }).replace('http://', 'https://');
        const response = new Response(body, originalResponse);

        const contentType = originalResponse.headers.get("Content-Type");

        if (contentType.startsWith("application/json")) {
            return response;
        } else {
            return originalResponse;
        }
    },
};

Mixed Content エラーなく <iframe src="https://... として表示されることを確認できます。

image.png

まとめ

今回、例えば Web アプリの「絶対 URL 指定に http を使わない」等の改修が間に合わない場合に、 Cloudflare の Automatic HTTPS Rewrites や Snippets を使って httphttps に書き換え、Mixed Content エラーを回避できることを確認しました。

ただ、長期的な目線では、Web アプリ側で「絶対 URL 指定に http を使わない」等の改修を反映できれば、構成上もシンプルにできるため、ベストと思います。

参考: Snippets と Workers の違い

Snippets Workers
Use Case HTTP modifications Full-stack applications
Runtime Support JavaScript WASM (JavaScript, Python, Rust and more)
Subrequests Pro: 2 per request
Business: 3 per request
Enterprise: 5 per request
Free: 50 per request
Standard: 1,000 per request
Maximum Execution Time 5 ms Free: 10 ms
Standard: 30 seconds
Environment Variables :x: :white_check_mark:​​
Bindings (KV, DO, R2, D1, etc.) :x: :white_check_mark:
Wrangler CLI :x: :white_check_mark:
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?