Framework
Sandbox Pages

サンドボックスページ

サンドボックスページは、異なるCSP(コンテンツセキュリティポリシー)制限を持つ特別な拡張機能ページです。例えば、サンドボックスページ内では任意のコードをevalすることが可能です。拡張機能ページと比較してより多くの権限を持つ安全なコンテキストでコードを動的に実行するために、サンドボックスページを使用します。

サンドボックスページは、CSUIと同様にUIコンポーネントをマウントしたり、単純なスクリプトを実行したりできます。次の例では、サンドボックスページから任意のコードをevalし、メッセージパッシングを介して結果を呼び出し元に送り返す機能を示しています。

まず、サンドボックスページを追加します。

  1. ソースディレクトリ(プロジェクトルートまたはsrc)にsandbox.tsファイルまたはsandboxes/<name>.tsファイルを作成します。
  2. 次のスクリプトをエクスポートします。
sandbox.ts
export const life = 42
 
window.addEventListener("message", async function (event) {
  const source = event.source as {
    window: WindowProxy
  }
 
  source.window.postMessage(eval(event.data), event.origin)
})

上記のスクリプトは、ウィンドウスコープからのmessageイベントをリッスンし、dataプロパティを介して呼び出し元から送信されたコードをevalします。サンドボックスページは、拡張機能バンドル内のsandbox.htmlまたはsandboxes/<name>.htmlで利用可能になります。このページにメッセージを送信するには、iframe内にマウントし、postMessage APIを呼び出す必要があります。popup.tsx拡張機能ページで実行してみましょう。

popup.tsx
import { useEffect, useRef, useState } from "react"
 
function IndexPopup() {
  const iframeRef = useRef<HTMLIFrameElement>(null)
 
  useEffect(() => {
    window.addEventListener("message", (event) => {
      console.log("EVAL output: " + event.data)
    })
  }, [])
 
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        padding: 16
      }}>
      <button
        onClick={() => {
          iframeRef.current.contentWindow.postMessage("10 + 20", "*")
        }}>
        Trigger iframe eval
      </button>
      <iframe src="sandbox.html" ref={iframeRef} style={{ display: "none" }} />
    </div>
  )
}
 
export default IndexPopup

ユーザーが「Trigger iframe eval」ボタンをクリックすると、サンドボックスページ内で実行されたevalの結果が表示されます。

詳細については、rfc-263 (opens in a new tab)を参照してください。