Security Sandbox
Isolated execution environment for untrusted HoloScript code. Uses vm2-based sandboxing with resource limits, capability restrictions, and security auditing.
Overview
The Security Sandbox runs user-generated code safely without access to host system resources, file system, or sensitive environment variables.
Installation
bash
npm install @holoscript/security-sandboxQuick Start
typescript
import { Sandbox } from '@holoscript/security-sandbox';
const sandbox = new Sandbox({
timeout: 5000, // 5 second execution limit
memory: 128 * 1024 * 1024, // 128 MB limit
});
// Execute untrusted code
const result = await sandbox.run(`
return {
sum: 1 + 2 + 3,
message: 'Hello from sandbox!'
};
`);
console.log(result.output); // { sum: 6, message: 'Hello from sandbox!' }
console.log(result.executionTime); // ms
console.log(result.safe); // true (no violations)Execution Context
Pass Data In
typescript
const result = await sandbox.run(
`
return {
doubled: input.value * 2,
name: input.name.toUpperCase()
};
`,
{
input: {
value: 42,
name: 'alice',
},
}
);
console.log(result.output); // { doubled: 84, name: 'ALICE' }Resource Limits
typescript
const sandbox = new Sandbox({
timeout: 5000, // Max execution time
memory: 256 * 1024 * 1024, // Max memory
cpuTicks: 100000, // Instruction limit
maxArrayLength: 10000, // Array size limit
maxStringLength: 1000000, // String size limit
});Capability Restrictions
typescript
const sandbox = new Sandbox({
allowedGlobals: [
'Math',
'JSON',
'Array',
'String',
'Object',
// No: fs, require, process, child_process, etc.
],
deniedPatterns: [
'eval', // Block eval
'Function', // Block Function constructor
'__proto__', // Block prototype pollution
'constructor', // Block constructor access
],
});Safety Verification
typescript
const result = await sandbox.run(userCode);
if (!result.safe) {
console.error('Code violated security policy');
console.log(result.violations); // What was attempted
console.log(result.securityGrade); // A-F rating
}
// A = No access attempts
// B = Attempted benign access
// C = Challenged access (blocked)
// D = Multiple violations
// F = Critical violationsAudit Logging
typescript
const sandbox = new Sandbox({
audit: true, // Log all operations
});
const result = await sandbox.run(userCode);
console.log(result.auditLog); // Array of all operations attempted
// [
// { operation: 'global_access', name: 'Math' },
// { operation: 'function_call', name: 'Math.random' },
// { operation: 'array_access', index: 0 },
// { operation: 'blocked', reason: 'fs not in allowedGlobals' }
// ]Error Handling
typescript
try {
const result = await sandbox.run(untrustedCode);
if (result.safe) {
console.log('Output:', result.output);
} else {
console.error('Unsafe code detected:', result.violations);
}
} catch (error) {
if (error.code === 'TIMEOUT') {
console.error('Code execution exceeded timeout');
} else if (error.code === 'MEMORY_EXCEEDED') {
console.error('Code used too much memory');
} else if (error.code === 'SYNTAX_ERROR') {
console.error('Invalid code:', error.message);
}
}Advanced: Custom Sandbox
typescript
import { createSandbox } from '@holoscript/security-sandbox';
const customSandbox = createSandbox({
// Core limits
timeout: 10000,
memory: 512 * 1024 * 1024, // 512 MB
// Allowed APIs
allowedGlobals: ['Math', 'JSON', 'Array', 'String', 'Object', 'Date'],
allowedModules: [], // No require()
// Security
preventEval: true,
preventFunctionConstructor: true,
preventPrototypeAccess: true,
// Auditing
audit: true,
auditHooks: {
onGlobalAccess: (name) => console.log(`Accessed ${name}`),
onFunctionCall: (fn) => console.log(`Called ${fn.name}`),
onPropertyAccess: (obj, prop) => console.log(`Accessed ${obj}.${prop}`),
},
});Testing Code Safety
typescript
const tests = [
{
name: 'Safe arithmetic',
code: 'return 2 + 2;',
expectedSafe: true,
},
{
name: 'Attempt file read',
code: 'return require("fs").readFileSync("/etc/passwd");',
expectedSafe: false,
},
{
name: 'Complex algorithm',
code: `
let sum = 0;
for (let i = 0; i < 1000; i++) sum += i;
return sum;
`,
expectedSafe: true,
},
];
for (const test of tests) {
const result = await customSandbox.run(test.code);
console.log(test.name, result.safe === test.expectedSafe ? '✓' : '✗');
}Integration with HoloScript
typescript
import { Sandbox } from '@holoscript/security-sandbox';
import { parse } from '@holoscript/core';
// Parse HoloScript composition
const holo = parse(`
composition "Game" {
template "Gameplay" {
action calculateScore(multiplier) {
// User-provided logic
return this.baseScore * multiplier;
}
}
}
`);
// Execute action in sandbox
const sandbox = new Sandbox();
const result = await sandbox.run(
`
return calculateScore(2.5);
`,
{
calculateScore: (mult) => 100 * mult,
baseScore: 100,
}
);Environment Variables
bash
# Sandbox limits
SANDBOX_TIMEOUT=5000
SANDBOX_MEMORY=268435456 # 256 MB in bytes
SANDBOX_CPU_TICKS=100000
# Security
SANDBOX_PREVENT_EVAL=true
SANDBOX_PREVENT_ACCESS=true
# Auditing
SANDBOX_AUDIT=true
SANDBOX_AUDIT_VERBOSE=falsePerformance
- Overhead: ~1-5ms per execution
- Memory: ~2-5MB per sandbox instance
- Max concurrency: Limited by system resources
Use connection pooling for high-throughput scenarios:
typescript
import { SandboxPool } from '@holoscript/security-sandbox';
const pool = new SandboxPool({
size: 10, // 10 sandboxes
timeout: 5000,
});
// Distribute work across pool
const promises = userCodes.map((code) => pool.run(code));
const results = await Promise.all(promises);Best Practices
- Always validate before sandboxing — Catch syntax errors early
- Set reasonable timeouts — 5 seconds for typical code, 30s max
- Monitor resource usage — Alert on high memory/CPU consumption
- Audit all executions — Log for security analysis
- Use capability allowlists — Deny by default, allow specific APIs
- Test edge cases — See what happens at limits
- Update vm2 regularly — Security patches are critical
See Also
- Auth — User authentication before sandbox execution
- AI Validator — Detect hallucinations in generated code before sandboxing
- Partner SDK — Safe webhook execution