Manifest V3 のセキュリティを強化
これは、拡張機能 Service Worker の一部ではないコードに必要な変更について説明する 3 つのセクションの最後の部分です。拡張機能のセキュリティを改善するために必要な変更について説明しています。他の 2 つのセクションでは、Manifest V3 へのアップグレードに必要なコードの更新と、ブロック中のウェブリクエストの置き換えについて説明します。
任意の文字列の実行を削除する
executeScript()
、eval()
、new Function()
を使用して外部ロジックを実行することはできなくなりました。
- すべての外部コード(JS、Wasm、CSS)を拡張機能のバンドルに移動します。
- スクリプトとスタイルの参照を更新して、拡張機能バンドルからリソースを読み込む。
chrome.runtime.getURL()
を使用して、実行時にリソース URL を作成します。- サンドボックス化された iframe を使用する:
eval
とnew Function(...)
は、サンドボックス化された iframe でも引き続きサポートされています。詳しくは、サンドボックス化された iframe に関するガイドをご覧ください。
executeScript()
メソッドが tabs
名前空間ではなく scripting
名前空間に配置されるようになりました。呼び出しの更新については、executeScript()
を移動するをご覧ください。
次のような特殊なケースでは、任意の文字列を実行できます。
- insertCSS を使用して、リモートでホストされているスタイルシートをウェブページに挿入する
chrome.devtools
を使用する拡張機能の場合: inspectWindow.eval で、検査対象のページのコンテキストで JavaScript を実行できます。- デバッガ拡張機能では、chrome.debugger.sendCommand を使用してデバッグ ターゲットで JavaScript を実行できます。
リモートでホストされているコードを削除する
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
プロパティを使用して変数を渡すことができます。
let name = 'World!'; chrome.tabs.executeScript({ code: `alert('Hello, ${name}!')` });
バックグラウンド スクリプト ファイル内。
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 つのプロパティをサポートする辞書になりました。
{ ... "content_security_policy": "default-src 'self'" ... }
{ ... "content_security_policy": { "extension_pages": "default-src 'self'", "sandbox": "..." } ... }
extension_pages
: 拡張機能のコンテキスト(HTML ファイルやサービス ワーカーなど)を指します。
sandbox
: 拡張機能が使用するサンドボックス化された拡張機能ページを指します。
サポートされていないコンテンツ セキュリティ ポリシーを削除する
Manifest V3 では、Manifest V2 で許可されていた "extension_pages"
フィールドの特定のコンテンツ セキュリティ ポリシー値が禁止されています。具体的には、Manifest V3 でリモートコード実行を許可するアプリは許可されません。script-src,
、object-src
、worker-src
ディレクティブには、次の値のみを指定できます。
self
none
wasm-unsafe-eval
- パッケージ化されていない拡張機能のみ: 任意の localhost ソース(
http://localhost
、http://127.0.0.1
、またはこれらのドメインの任意のポート)
sandbox
のコンテンツ セキュリティ ポリシーの値には、このような新しい制限はありません。