121Implement a sandboxed JavaScript execution environment using an isolated iframe or worker, with a clearly defined security boundary
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.warnandconsole.errorcalls as strings inlogs. - If the code throws (or its promise rejects), reject with an
Errorcarrying the same message. - If it runs longer than
timeoutms (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.
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.