@stevenleep/sandbox
Version:
A powerful JavaScript sandbox library that provides multiple sandbox implementation options for safely executing untrusted code in browser environments.
130 lines (110 loc) ⢠4.57 kB
text/typescript
// Define TypeScript interface for Window with our custom properties
declare global {
interface Window {
___outsideVar?: string;
___testVariable?: string;
}
}
import { getBestSandboxType, createSandbox, SandboxType } from '../src';
// Function to run the demo with each sandbox type
async function runSandboxDemo(sandboxType: SandboxType) {
console.log(`\n=== Testing Sandbox Type: ${sandboxType} ===`);
// Create a sandbox with maximum isolation
const sandbox = createSandbox(sandboxType, {
name: `isolated-${sandboxType}-sandbox`,
// List properties that should be restricted from modification
blacklist: [
'localStorage',
'sessionStorage',
'indexedDB',
'openDatabase',
'WebSocket',
'XMLHttpRequest',
'fetch',
'document'
],
// Enforce strict mode for full isolation
strictMode: true,
// Set resource limits
timeLimit: 2000,
memoryLimit: 50 * 1024 * 1024, // 50MB
// Enable security features
security: {
preventPrototypePollution: true,
preventSensitiveAPIs: true
},
// For ShadowRealm, force iframe fallback for demo consistency
...(sandboxType === SandboxType.ShadowRealm ? { forceIframe: true } : {})
});
console.log(`Sandbox created: ${sandbox.name}`);
// Define a global variable before activating the sandbox
window.___outsideVar = "I'm defined outside the sandbox";
console.log("Global variable before sandbox:", window.___outsideVar);
// Activate the sandbox before using it
sandbox.activate();
// Execute some test code in the sandbox
sandbox.execScript(`
// This should be contained within the sandbox
window.___testVariable = "I'm isolated in the sandbox";
console.log("Hello from the ${sandboxType} sandbox!");
// This shouldn't modify the real window's property
window.___outsideVar = "Modified inside sandbox";
console.log("Outside variable accessed inside sandbox:", window.___outsideVar);
`);
// Verify that variables defined in the sandbox are accessible within the sandbox
const sandboxResult = sandbox.execScript(`
console.log("Sandbox variable value:", window.___testVariable);
return {
insideVar: window.___testVariable,
outsideVarSandboxView: window.___outsideVar
};
`);
console.log("Result from sandbox execution:", sandboxResult);
// Verify complete isolation from the global window
console.log("Global ___testVariable (should be undefined):", window.___testVariable);
console.log("Global ___outsideVar (should be unchanged):", window.___outsideVar);
// Test resource limits and timeouts
if (typeof sandbox.execScriptAsync === 'function') {
console.log("\nTesting async execution with timeout...");
try {
const asyncResult = await sandbox.execScriptAsync(`
return new Promise(resolve => {
setTimeout(() => resolve("Async success"), 100);
});
`, 500);
console.log("Async result:", asyncResult);
} catch (error) {
console.error("Async execution error:", error);
}
}
// Clean up when finished
console.log("\nCleaning up resources...");
sandbox.deactivate();
sandbox.destroy();
console.log(`${sandboxType} sandbox destroyed.`);
}
// Main function to test all sandbox types
async function testAllSandboxTypes() {
console.log("š Secure Sandbox Demo - Testing All Sandbox Types š");
console.log("---------------------------------------------------");
// Get the best available sandbox type for the current environment
const recommendedType = getBestSandboxType();
console.log(`Recommended sandbox type for this environment: ${recommendedType}`);
// Test all sandbox types
const sandboxTypes = [
SandboxType.Proxy,
SandboxType.WithEval,
SandboxType.Snapshot,
SandboxType.ShadowRealm,
];
for (const type of sandboxTypes) {
try {
await runSandboxDemo(type);
} catch (error) {
console.error(`Error testing ${type} sandbox:`, error);
}
}
console.log("\nā
Sandbox Testing Complete");
}
// Run the demo
testAllSandboxTypes().catch(error => console.error("Demo failed:", error));