FrontendPro

121Implement a sandboxed JavaScript execution environment using an isolated iframe or worker, with a clearly defined security boundary

hardAbout 75 minutesCodingsecurityweb-workerssandboxingpostMessage

Problem

Run untrusted code (a user's plugin, a formula, an exercise solution like on this site) without letting it touch your page, steal cookies, call your APIs or freeze the tab.

Implement createSandbox({ timeout = 1000 } = {}) returning { run(code) }, where code is the body of a function (it may return a value and may use await). run resolves with { result, logs } or rejects:

  • Run each call in a fresh dedicated Worker created from a Blob URL, so runs share nothing and have no DOM, cookies or localStorage.
  • Before the user code runs, remove network and persistence APIs from the worker's global scope: fetch, XMLHttpRequest, WebSocket, EventSource, importScripts, indexedDB, caches.
  • Capture console.log, console.warn and console.error calls as strings in logs.
  • If the code throws (or its promise rejects), reject with an Error carrying the same message.
  • If it runs longer than timeout ms (an infinite loop included), terminate the worker and reject with an error named "TimeoutError". The page must stay responsive the whole time.
  • If the result cannot be cloned (for example a function), reject with a clear error.

Document the security boundary: what the sandbox protects against, and what it does not.

Try it yourself

Write your solution, run it, then submit to check it against the tests.

App.jsxReact + DOM

Step-by-step

A Worker runs on another thread with its own global scope: no document, no window, no cookies, no localStorage, and an infinite loop there cannot freeze the page, because you can terminate() it.

Unlock the full solution

What's inside

  • Step-by-step
  • Approach
  • Solution
  • Complexity
  • Edge cases
  • Follow-up questions
  • Tests

Includes 2 code listings, 5 edge cases, 4 follow-up questions.

One-time payment by UPI, card or net banking. Launch price.

All 150 answersOne payment, yours forever