@web-engine-dev/sandbox
Secure script execution sandbox for UGC platforms with capability-based security.
Features
- Script Isolation: Secure JavaScript execution
- Capability System: Fine-grained permissions
- Resource Limits: CPU/memory constraints
- API Surface: Controlled API exposure
- Timeout Protection: Prevent infinite loops
Installation
bash
npm install @web-engine-dev/sandbox
# or
pnpm add @web-engine-dev/sandboxQuick Start
typescript
import { Sandbox, Capabilities } from '@web-engine-dev/sandbox';
// Create sandbox
const sandbox = new Sandbox({
capabilities: [Capabilities.READ_ENTITY, Capabilities.MODIFY_ENTITY, Capabilities.SPAWN_ENTITY],
memoryLimit: 50 * 1024 * 1024, // 50MB
timeLimit: 1000, // 1 second per call
});
// Execute user script
const result = await sandbox.execute(userScript, {
world: wrappedWorld,
input: wrappedInput,
});API Overview
Sandbox Creation
typescript
const sandbox = new Sandbox({
// Allowed capabilities
capabilities: [Capabilities.READ_ENTITY, Capabilities.MODIFY_ENTITY],
// Resource limits
memoryLimit: 50 * 1024 * 1024,
timeLimit: 1000,
maxStackDepth: 100,
// API exposure
globals: {
console: sandboxedConsole,
Math: Math,
},
});Capabilities
| Capability | Description |
|---|---|
READ_ENTITY | Read entity data |
MODIFY_ENTITY | Modify entity components |
SPAWN_ENTITY | Create new entities |
DESTROY_ENTITY | Delete entities |
PLAY_AUDIO | Play sounds |
NETWORK_REQUEST | Make HTTP requests |
STORAGE_READ | Read persistent storage |
STORAGE_WRITE | Write persistent storage |
Script Execution
typescript
// Execute code
const result = await sandbox.execute(code, context);
// Execute with timeout
const result = await sandbox.execute(code, context, {
timeout: 500,
});
// Handle errors
try {
await sandbox.execute(untrustedCode, context);
} catch (err) {
if (err instanceof TimeoutError) {
console.log('Script took too long');
} else if (err instanceof PermissionError) {
console.log('Script tried to do something forbidden');
}
}API Wrapping
typescript
// Create safe wrapper
const wrappedWorld = sandbox.wrap(world, {
allowedMethods: ['spawn', 'query', 'getComponent'],
blockedMethods: ['destroy', 'clear'],
});
// Pass to script
await sandbox.execute(script, { world: wrappedWorld });