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
Namespace ではなく scripting
Namespace にあります。呼び出しの更新については、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
のコンテンツ セキュリティ ポリシーの値には、このような新しい制限はありません。