JavaScript Sandboxes for Secure Micro‑Frontend Apps: Techniques & Examples
This article explains the concept of sandbox security mechanisms, explores their use cases in iPaaS API orchestration and micro‑frontend applications, compares eval, Function, with + proxy techniques, presents JavaScript, iframe and Node vm sandbox implementations, and details practical deployments within the Kraken framework and a centralized approval service.
1. Introduction
Sandbox is a security mechanism that isolates program execution to protect the system. Developers frequently encounter sandbox environments such as Docker containers, CodeSandbox demos, and dynamic script execution.
2. Use Cases
Typical scenarios in the company include iPaaS visual API orchestration where custom Groovy scripts run in a sandbox, and micro‑frontend applications that need isolated global objects, routing, and state management.
3. JavaScript Sandbox Research
3.1 eval and Function
Both eval and the Function constructor can execute external code, but they expose global variables and cannot provide true isolation.
<code>// Bad code using eval
function looseJsonParse(obj){
return eval(`(${obj})`);
}
console.log(looseJsonParse("{a:(4-1), b:function(){}, c:new Date()}"));
// Better code using Function
function looseJsonParse(obj){
return Function(`"use strict";return (${obj})`)();
}
console.log(looseJsonParse("{a:(4-1), b:function(){}, c:new Date()}"));
</code>3.2 with + Function + Proxy
3.2.1 with keyword
The with statement changes the scope chain, but it is prohibited in strict mode and is generally discouraged.
3.2.2 ES6 Proxy
Proxy can intercept property access, assignment, enumeration, and function calls.
<code>const handler = {
get: function (obj, prop) {
return prop in obj ? obj[prop] : 'weimob';
},
};
const p = new Proxy({}, handler);
p.a = 2023;
p.b = undefined;
console.log(p.a, p.b); // 2023 undefined
console.log('c' in p, p.c); // false, weimob
</code>3.2.3 Symbol.unscopables
If Symbol.unscopables is set to true, the with scope is ignored, allowing sandbox escape, so it must be handled explicitly.
3.2.4 Sandbox implementation
<code>function sandbox(code, context) {
context = context || Object.create(null);
const fn = new Function('context', `with(context){return (${code})}`);
const proxy = new Proxy(context, {
has(target, key) {
if (["console", "setTimeout", "Date"].includes(key)) {
return true;
}
if (!target.hasOwnProperty(key)) {
throw new Error(`Illegal operation for key ${key}`);
}
return target[key];
},
get(target, key, receiver) {
if (key === Symbol.unscopables) {
return undefined;
}
return Reflect.get(target, key, receiver);
}
});
return fn.call(proxy, proxy);
}
sandbox('3+2'); // 5
sandbox('console.log("微盟-智慧商业服务商")'); // Cannot read property 'log' of undefined
sandbox('console.log("微盟-智慧商业服务商")', {console: window.console}); // 微盟-智慧商业服务商
</code>3.3 iframe based sandbox
Creating an iframe provides a native browser isolation layer; scripts run inside the iframe cannot affect the parent page.
<code>const parent = window;
const frame = document.createElement('iframe');
// Restrict iframe capabilities
frame.sandbox = 'allow-same-origin';
document.body.appendChild(frame);
const sandboxGlobal = frame.contentWindow;
</code>3.4 Node runtime sandbox
3.4.1 Native vm module
The vm module creates a V8 context that can execute code with a given context object.
<code>const vm = require('node:vm');
const x = 1;
const context = { x: 2 };
vm.createContext(context); // Contextify the object.
const code = 'x += 40; var y = 17;';
vm.runInContext(code, context);
console.log(context.x); // 42
console.log(context.y); // 17
console.log(x); // 1; y is not defined.
</code>Node's vm is not a security mechanism; untrusted code can escape via prototype chains.
node:vm module is not a security mechanism. Do not use it to run untrusted code.
3.4.2 Insecure reasons
Running code with vm.runInNewContext can access the global constructor and escape the sandbox.
<code>const vm = require('vm');
vm.runInNewContext('this.constructor.constructor("return process")().exit()');
</code>3.4.3 Solution
Provide a clean context object without a prototype chain to prevent escape.
<code>const vm = require('vm');
let sandBox = Object.create(null);
sandBox.title = '微盟-智慧商业服务商';
sandBox.console = console;
vm.runInNewContext('console.log(title)', sandBox);
</code>4. Practical Deployment
4.1 Kraken micro‑frontend framework
Kraken uses a sandbox based on a fake window and Proxy to give each micro‑frontend its own module, style, route, and state isolation, while supporting data sharing and event communication.
4.1.1 JS isolation
Create a sandbox instance and declare global APIs such as addEventListener, setTimeout, createElement, and intercept property access.
Use with to limit the scope of the execution context.
Parse dynamic JS with Function, intercept object access with Proxy, and bind this to the proxy.
4.1.2 CSS isolation
CSS isolation is achieved with CSS modules (hashed class names) and project‑level namespaces.
4.1.3 Data sharing & communication
Kraken exposes
kraken.datafor read/write data sharing and implements an event bus for parent‑child, sibling, and global communication.
4.2 Centralized approval service
The service enforces internal change management by requiring approval workflows for production changes. Business systems can integrate without custom code by configuring change points.
4.2.1 Node approval workflow
The gateway layer intercepts API calls, creates approval tickets, and allows scripts to extend ticket details.
4.2.2 Dynamic extension scripts
Business users can register a script that runs in a Node sandbox before ticket creation to enrich the details.
<code>/**
* Execute a user‑provided script string
* @param {String} code JavaScript code
* @param {Object} context Context visible to the code
*/
async function execScript(code, context) {
try {
const contextObject = Object.assign(context, {
setTimeout,
request
});
return vm.runInNewContext(code, contextObject);
} catch (error) {
return Promise.reject(error);
}
}
</code>Example user script:
<code>(() => ({ objectAction: `发布online:${packageName}@${packageVersion}` }))()
</code>4.2.3 Summary
Although the vm module is not a security guarantee, the service runs inside a trusted internal network and adds manual review of scripts, providing sufficient safety for internal use.
5. Conclusion and Outlook
The article introduced sandbox concepts, application scenarios, and concrete JavaScript sandbox implementations for large‑scale front‑end platforms. Real‑world deployments show that sandbox strategies must be tailored to business needs, balancing flexibility and security.
Weimob Technology Center
Official platform of the Weimob Technology Center
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.