Framework
Sandbox Pages

Sandbox Pages

Sandbox Pages are special extension pages with a different set of CSP restrictions. For example, it is possible to eval arbitrary code inside a sandbox page. Use the sandbox page to dynamically run code in a secure context with more privileges compared to an extension page.

A sandbox page can mount UI components similar to a CSUI or execute simple scripts. The following example showcases the ability to eval arbitrary code from a sandbox page and communicate the result back to the caller via message passing.

First, we want to add a sandbox page:

  1. Create a sandbox.ts file or a sandboxes/<name>.ts file in the source directory (project root or src)
  2. Export the following script:
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)
})

The script above listens to a message event from the window scope, and evals the code sent by the caller via the data property. The sandbox page is now available under sandbox.html OR sandboxes/<name>.html in the extension bundle. To send messages to this page, we will need to mount it inside an iframe, and invoke the postMessage API. Let's do so in a popup.tsx extension page:

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

When a user clicks the trigger iframe eval, they will see the result of the eval done inside the sandbox page.

See rfc-263 (opens in a new tab) for more details.