拡張機能のセキュリティを強化

Manifest V3 のセキュリティ強化

これは、拡張機能の Service Worker に含まれないコードに必要な変更について説明する 3 つのセクションの最後です。拡張機能のセキュリティを強化するために必要な変更について説明します。他の 2 つのセクションでは、Manifest V3 へのアップグレードに必要なコードの更新と、ブロック中のウェブリクエストの置き換えについて説明します。

任意の文字列の実行を削除

executeScript()eval()new Function() を使用して外部ロジックを実行できなくなります。

  • すべての外部コード(JS、Wasm、CSS)を拡張機能バンドルに移動します。
  • スクリプトとスタイルの参照を更新して、拡張機能バンドルからリソースを読み込む。
  • chrome.runtime.getURL() を使用して、ランタイムでリソース URL をビルドします。
  • サンドボックス化された iframe を使用する: evalnew Function(...) は、サンドボックス化された iframe でも引き続きサポートされています。詳しくは、サンドボックス化された iframe に関するガイドをご覧ください。

executeScript() メソッドは、tabs Namespace ではなく scripting Namespace にあります。呼び出しの更新については、executeScript() を移動するをご覧ください。

任意の文字列を実行できる特殊なケースがいくつかあります。

リモートでホストされているコードを削除する

Manifest V3 では、拡張機能のすべてのロジックを拡張機能パッケージに含める必要があります。Chrome ウェブストアのポリシーに基づき、リモートでホストされているファイルを読み込んで実行することはできなくなりました。次に例を示します。

  • デベロッパーのサーバーから取得した JavaScript ファイル。
  • CDN でホストされているライブラリ。
  • リモートでホストされているコードを動的に取得するバンドルされたサードパーティ ライブラリ。

ユースケースとリモート ホスティングを行う理由に応じて、他の方法も使用できます。このセクションでは、検討すべきアプローチについて説明します。リモートでホストされているコードの処理で問題が発生した場合は、ガイダンスをご利用ください。

構成ドリブンの機能とロジック

拡張機能は、実行時にリモート構成(JSON ファイルなど)を読み込んでキャッシュに保存します。どの機能が有効になるかは、キャッシュに保存された構成によって決まります。

リモート サービスによる外部ロジック

拡張機能がリモート ウェブサービスを呼び出します。これにより、コードを非公開にして必要に応じて変更しながら、Chrome ウェブストアに再送信する余分なオーバーヘッドを回避できます。

リモートでホストされるコードをサンドボックス化された iframe に埋め込む

リモートでホストされるコードは、サンドボックス化された iframe でサポートされています。なお、コードで埋め込みページの DOM へのアクセスが必要な場合は、この方法は機能しません。

サードパーティ ライブラリをバンドルする

以前は外部サーバーから読み込んでいた React や Bootstrap などの一般的なフレームワークを使用している場合は、圧縮ファイルをダウンロードしてプロジェクトに追加し、ローカルにインポートできます。次に例を示します。

<script src="./react-dom.production.min.js"></script>
<link href="./bootstrap.min.css" rel="stylesheet">

サービス ワーカーにライブラリを含めるには、マニフェストで "background.type" キー"module" に設定し、import ステートメントを使用します。

タブ挿入スクリプトで外部ライブラリを使用する

外部ライブラリを実行時に読み込むには、scripting.executeScript() を呼び出すときに files 配列に追加します。実行時にリモートでデータを読み込むことはできます。

chrome.scripting.executeScript({
  target: {tabId: tab.id},
  files: ['jquery-min.js', 'content-script.js']
});

関数を挿入する

より動的なものが必要な場合は、scripting.executeScript() の新しい func プロパティを使用して、関数をコンテンツ スクリプトとして挿入し、args プロパティを使用して変数を渡すことができます。

Manifest V2
let name = 'World!';
chrome.tabs.executeScript({
  code: `alert('Hello, ${name}!')`
});

バックグラウンド スクリプト ファイル。

Manifest V3
async function getCurrentTab() {/* ... */}
let tab = await getCurrentTab();

function showAlert(givenName) {
  alert(`Hello, ${givenName}`);
}

let name = 'World';
chrome.scripting.executeScript({
  target: {tabId: tab.id},
  func: showAlert,
  args: [name],
});

バックグラウンド サービス ワーカー。

Chrome 拡張機能サンプル リポジトリには、ステップ実行できる関数インジェクションの例が含まれています。getCurrentTab() の例については、その関数のリファレンスをご覧ください。

他の回避策を探す

上記のアプローチがユースケースに役立たない場合は、別のソリューション(別のライブラリへの移行など)を見つけるか、ライブラリの機能を使用するための他の方法を見つける必要があります。たとえば、Google アナリティクスの場合は、Google アナリティクス 4 ガイドに記載されているように、リモートでホストされている公式の JavaScript バージョンを使用する代わりに、Google Measurement Protocol に切り替えることができます。

コンテンツ セキュリティ ポリシーを更新する

"content_security_policy"manifest.json ファイルから削除されていませんが、"extension_pages""sandbox" の 2 つのプロパティをサポートする辞書になりました。

Manifest V2
{
  ...
  "content_security_policy": "default-src 'self'"
  ...
}
Manifest V3
{
  ...
  "content_security_policy": {
    "extension_pages": "default-src 'self'",
    "sandbox": "..."
  }
  ...
}

extension_pages: 拡張機能のコンテキスト(HTML ファイルやサービス ワーカーなど)を指します。

sandbox: 拡張機能で使用されるサンドボックス化された拡張機能ページを指します。

サポートされていないコンテンツ セキュリティ ポリシーを削除する

Manifest V3 では、Manifest V2 で許可されていた "extension_pages" フィールドの特定のコンテンツ セキュリティ ポリシー値が禁止されています。具体的には、Manifest V3 ではリモートコード実行を許可する機能は禁止されています。script-src, object-srcworker-src ディレクティブには、次の値のみを指定できます。

  • self
  • none
  • wasm-unsafe-eval
  • 展開されていない拡張機能のみ: 任意の localhost ソース(http://localhosthttp://127.0.0.1、またはそれらのドメイン上の任意のポート)

sandbox のコンテンツ セキュリティ ポリシーの値には、このような新しい制限はありません。