Run plugins in the most isolated environment that still lets them do their job. In process is the simplest and the least safe. A sandboxed iframe, a restricted script sandbox or a WebAssembly module give you real boundaries, but each one limits what the plugin can do and costs you API design work.
The four options
In process. The plugin runs with the same privileges as the host. VS Code is the clear example in its own documentation: the extension host has the same permissions as VS Code itself, so an extension can read and write files, make network requests and run external processes. That is great for power and poor for containment, so VS Code leans on marketplace checks, publisher trust and block lists.
Sandboxed iframe. The browser enforces a boundary. The MDN reference for the iframe sandbox attribute explains that without the allow-same-origin token the content is treated as coming from a special origin that fails the same-origin policy. Chrome's extension guidance also notes that sandboxed iframes still support eval and remote code, which makes them a pressure valve for code you cannot bundle. The catch: a sandboxed page cannot touch the embedding page's DOM.
Restricted script sandbox. Figma runs plugin logic on the main thread inside a minimal JavaScript environment that does not expose browser APIs such as fetch or the DOM. Anything needing those goes into a separate iframe, and the two sides talk by message passing.
WebAssembly. The WebAssembly security documentation says each module executes in a sandboxed environment separated from the host runtime, and can only reach outside through the APIs the host provides. WASI, the system interface standard, states a belief that every project with a plugin model should consider it.
How they compare
| Runtime | Isolation | Power for plugin author | Main cost to you |
|---|---|---|---|
| In process | None beyond review | Highest | Heavy review and fast removal |
| Sandboxed iframe | Browser enforced | Medium | Message API design |
| Script sandbox | Host controlled | Medium | Build and maintain the environment |
| WebAssembly | Module boundary | Lower, language agnostic | Host API design, tooling |
How to choose
Ask four questions.
- What is the worst thing a plugin could do with full host power? If the answer includes customer data, avoid in process.
- Do plugins need the DOM or local files? If not, a sandboxed boundary is cheap to adopt.
- Who writes plugins? Internal teams can tolerate more trust than anonymous publishers.
- Can you ship a capability API? Isolation only works if the host exposes narrow, well-defined calls.
A boundary is not the whole answer
Isolation limits blast radius. It does not remove the need for permissions, review or a kill switch. A sandboxed plugin that is allowed to call your data API with a broad token can still leak data through that API. Treat the sandbox as one layer and the capability design as the main control.
Also watch the host side of the boundary. Every function you expose to a plugin is attack surface. Validate arguments, rate limit calls and log them.
Quick check
Does WebAssembly make a plugin safe by itself?
No. It gives memory and control flow isolation from the host, but the module can still misuse any capability the host hands it, so the capability list still matters.
Is an iframe sandbox the same as a security review?
No. The sandbox restricts what the page can do in the browser. It does not tell you whether the plugin's allowed actions are appropriate.
Safeguard does not choose a runtime for you, but it can scan the dependencies a plugin bundles and gate releases with policies. Start with the free scan on a sample plugin.
Sources
- Extension runtime security, Visual Studio Code
- iframe element and sandbox attribute, MDN
- How Plugins Run, Figma Developer Docs
- Security, WebAssembly
- Introduction, WASI.dev
- Improve extension security, Chrome for Developers
Last reviewed: 19 October 2026.