Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@enclave-vm/core

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@enclave-vm/core - npm Package Compare versions

Comparing version
2.10.0
to
2.10.1
+61
src/adapters/worker-pool/package.json
{
"name": "@enclave-vm/core",
"version": "2.10.1",
"description": "Sandbox runtime for secure JavaScript code execution",
"author": "AgentFront <info@agentfront.dev>",
"homepage": "https://github.com/agentfront/enclave",
"license": "Apache-2.0",
"keywords": [
"sandbox",
"vm",
"enclave",
"enclave-vm",
"agentscript",
"llm",
"javascript",
"execution",
"security",
"ast-guard"
],
"repository": {
"type": "git",
"url": "git+https://github.com/agentfront/enclave.git"
},
"bugs": {
"url": "https://github.com/agentfront/enclave/issues"
},
"main": "./dist/index.js",
"module": "./dist/esm/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"development": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./dist/esm/index.mjs",
"require": "./dist/index.js",
"default": "./dist/index.js"
}
},
"dependencies": {
"@babel/standalone": "^7.29.0",
"@enclave-vm/types": "2.10.1",
"@enclave-vm/ast": "2.10.1",
"acorn": "8.15.0",
"acorn-walk": "8.3.4",
"astring": "1.9.0",
"zod": "^4.3.6"
},
"peerDependencies": {
"@huggingface/transformers": "^3.2.2",
"vectoriadb": "^2.1.3"
},
"peerDependenciesMeta": {
"@huggingface/transformers": {
"optional": true
},
"vectoriadb": {
"optional": true
}
}
}
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// libs/core/src/adapters/worker-pool/worker-script.ts
var import_worker_threads = require("worker_threads");
var import_vm = __toESM(require("vm"));
var import_crypto = __toESM(require("crypto"));
// libs/core/src/adapters/worker-pool/errors.ts
var WorkerPoolError = class extends Error {
constructor(message) {
super(message);
this.name = "WorkerPoolError";
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
}
};
var MessageValidationError = class extends WorkerPoolError {
constructor(details) {
super(details ? `Invalid message: ${details}` : "Invalid message format");
this.name = "MessageValidationError";
}
};
var MessageSizeError = class extends WorkerPoolError {
/** Actual message size */
sizeBytes;
/** Maximum allowed size */
maxBytes;
constructor(sizeBytes, maxBytes) {
super(`Message size ${Math.round(sizeBytes / 1024)}KB exceeds limit ${Math.round(maxBytes / 1024)}KB`);
this.name = "MessageSizeError";
this.sizeBytes = sizeBytes;
this.maxBytes = maxBytes;
}
};
// libs/core/src/adapters/worker-pool/safe-deserialize.ts
var DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
var MAX_DEPTH = 50;
function safeDeserialize(raw, maxSizeBytes) {
if (maxSizeBytes !== void 0) {
const byteLength = Buffer.byteLength(raw, "utf-8");
if (byteLength > maxSizeBytes) {
throw new MessageSizeError(byteLength, maxSizeBytes);
}
}
try {
const parsed = JSON.parse(raw);
return sanitizeObjectWithDepthCheck(parsed, 0);
} catch (error) {
if (error instanceof MessageValidationError || error instanceof MessageSizeError) {
throw error;
}
throw new MessageValidationError("Invalid JSON");
}
}
function sanitizeObjectWithDepthCheck(value, depth) {
if (depth > MAX_DEPTH) {
throw new MessageValidationError(`Message exceeds maximum depth of ${MAX_DEPTH}`);
}
if (value === null || value === void 0) {
return value;
}
if (typeof value !== "object") {
return value;
}
if (Array.isArray(value)) {
return value.map((item) => sanitizeObjectWithDepthCheck(item, depth + 1));
}
const result = /* @__PURE__ */ Object.create(null);
for (const key of Object.keys(value)) {
if (!DANGEROUS_KEYS.has(key)) {
result[key] = sanitizeObjectWithDepthCheck(value[key], depth + 1);
}
}
return result;
}
function safeSerialize(value) {
return JSON.stringify(value, (key, val) => {
if (DANGEROUS_KEYS.has(key)) {
return void 0;
}
return val;
});
}
function sanitizeObject(value, depth = 0) {
if (depth > MAX_DEPTH) {
return void 0;
}
if (value === null || value === void 0) {
return value;
}
if (typeof value !== "object") {
return value;
}
if (Array.isArray(value)) {
return value.map((item) => sanitizeObject(item, depth + 1));
}
const result = /* @__PURE__ */ Object.create(null);
for (const key of Object.keys(value)) {
if (!DANGEROUS_KEYS.has(key)) {
result[key] = sanitizeObject(value[key], depth + 1);
}
}
return result;
}
// libs/core/src/adapters/worker-pool/worker-script.ts
var STACK_TRACE_HARDENING_CODE = `
(function() {
function __ag_redactStackString(stackStr) {
try {
if (typeof stackStr !== 'string' || !stackStr) return 'Error';
var lines = String(stackStr).split('\\n');
var header = lines[0] ? String(lines[0]) : 'Error';
var frameCount = (lines.length > 1) ? (lines.length - 1) : 0;
var max = frameCount;
if (max > 25) max = 25;
var out = [header];
for (var i = 0; i < max; i++) out.push(' at [REDACTED]');
if (frameCount > max) out.push(' at [REDACTED]');
return out.join('\\n');
} catch (e) {
return 'Error';
}
}
function __ag_prepareStackTrace(err, stack) {
try {
var name = (err && err.name) ? String(err.name) : 'Error';
var message = (err && err.message) ? String(err.message) : '';
var header = message ? (name + ': ' + message) : name;
if (!stack || !stack.length) return header;
var lines = [header];
var max = stack.length;
if (max > 25) max = 25;
for (var i = 0; i < max; i++) {
lines.push(' at [REDACTED]');
}
if (stack.length > max) {
lines.push(' at [REDACTED]');
}
return lines.join('\\n');
} catch (e) {
return 'Error';
}
}
function __ag_lockStackGetter(proto) {
if (!proto) return;
try {
var desc = Object.getOwnPropertyDescriptor(proto, 'stack');
if (!desc || typeof desc.get !== 'function') return;
var origGet = desc.get;
var origSet = desc.set;
Object.defineProperty(proto, 'stack', {
get: function() {
try {
return __ag_redactStackString(origGet.call(this));
} catch (e) {
return 'Error';
}
},
set: function(v) {
try {
if (typeof origSet === 'function') return origSet.call(this, v);
} catch (e) {}
},
configurable: false,
enumerable: false
});
} catch (e) {}
}
function __ag_lockPrepareStackTrace(ErrCtor) {
if (!ErrCtor) return;
try {
Object.defineProperty(ErrCtor, 'prepareStackTrace', {
value: __ag_prepareStackTrace,
writable: false,
configurable: false,
enumerable: false
});
} catch (e) {}
try {
Object.defineProperty(ErrCtor, 'stackTraceLimit', {
value: 25,
writable: false,
configurable: false,
enumerable: false
});
} catch (e) {}
}
__ag_lockStackGetter(Error && Error.prototype);
__ag_lockPrepareStackTrace(Error);
__ag_lockPrepareStackTrace(EvalError);
__ag_lockPrepareStackTrace(RangeError);
__ag_lockPrepareStackTrace(ReferenceError);
__ag_lockPrepareStackTrace(SyntaxError);
__ag_lockPrepareStackTrace(TypeError);
__ag_lockPrepareStackTrace(URIError);
try {
if (typeof AggregateError !== 'undefined') __ag_lockPrepareStackTrace(AggregateError);
} catch (e) {}
})();
`.trim();
var STACK_TRACE_HARDENING_SCRIPT = new import_vm.default.Script(STACK_TRACE_HARDENING_CODE);
var CODE_GENERATION_VIOLATION_DETECTOR_CODE = `
(function() {
var __ag_report = (typeof __ag_reportViolation__ === 'function') ? __ag_reportViolation__ : null;
function __ag_reportOnce(kind) {
try {
if (__ag_report) __ag_report(kind);
} catch (e) {}
}
// Capture intrinsics so later global sanitization can't break the proxy handler.
var __ag_Reflect = (typeof Reflect !== 'undefined') ? Reflect : null;
var __ag_Proxy = (typeof Proxy !== 'undefined') ? Proxy : null;
var __ag_Object = (typeof Object !== 'undefined') ? Object : null;
function __ag_wrapCtor(Ctor, kind) {
if (!Ctor || !__ag_Proxy || !__ag_Reflect || !__ag_Object) return;
try {
var proxy = new __ag_Proxy(Ctor, {
apply: function(target, thisArg, args) {
__ag_reportOnce(kind);
return __ag_Reflect.apply(target, thisArg, args);
},
construct: function(target, args, newTarget) {
__ag_reportOnce(kind);
return __ag_Reflect.construct(target, args, newTarget);
}
});
try {
if (Ctor.prototype) {
__ag_Object.defineProperty(Ctor.prototype, 'constructor', {
value: proxy,
writable: false,
configurable: false,
enumerable: false
});
}
} catch (e) {}
} catch (e) {}
}
try { __ag_wrapCtor(Function, 'CODE_GENERATION'); } catch (e) {}
try { __ag_wrapCtor((async function(){}).constructor, 'CODE_GENERATION'); } catch (e) {}
try { __ag_wrapCtor((function*(){}).constructor, 'CODE_GENERATION'); } catch (e) {}
try { __ag_wrapCtor((async function*(){}).constructor, 'CODE_GENERATION'); } catch (e) {}
})();
`.trim();
var CODE_GENERATION_VIOLATION_DETECTOR_SCRIPT = new import_vm.default.Script(CODE_GENERATION_VIOLATION_DETECTOR_CODE);
var port = import_worker_threads.parentPort;
if (!port) {
throw new Error("worker-script.ts must run inside a worker thread");
}
var DANGEROUS_GLOBALS = [
"parentPort",
"workerData",
"threadId",
"isMainThread",
"MessagePort",
"MessageChannel",
"BroadcastChannel",
"Worker",
"SharedArrayBuffer",
"Atomics"
];
for (const name of DANGEROUS_GLOBALS) {
try {
Object.defineProperty(globalThis, name, {
value: void 0,
writable: false,
configurable: false
});
} catch {
}
}
var currentExecution = null;
var pendingToolCalls = /* @__PURE__ */ new Map();
port.on("message", async (raw) => {
try {
const msg = safeDeserialize(raw);
switch (msg.type) {
case "execute":
await handleExecute(msg);
break;
case "tool-response":
handleToolResponse(msg);
break;
case "memory-report":
handleMemoryReport();
break;
case "abort":
handleAbort(msg.requestId);
break;
case "terminate":
handleTerminate(msg.graceful);
break;
default:
console.error("Unknown message type:", msg.type);
}
} catch (error) {
console.error("Worker message handler error:", error);
}
});
async function handleExecute(msg) {
const startTime = Date.now();
currentExecution = {
id: msg.requestId,
aborted: false,
config: msg.config,
stats: {
duration: 0,
toolCallCount: 0,
iterationCount: 0,
startTime,
endTime: 0
}
};
try {
const sandbox = createSandbox(msg.requestId, msg.config);
const context = import_vm.default.createContext(sandbox, {
codeGeneration: { strings: false, wasm: false }
});
const isStrictOrSecure = msg.config.securityLevel === "STRICT" || msg.config.securityLevel === "SECURE";
const policyViolation = {};
const shouldHardenStacks = msg.config.sanitizeStackTraces ?? true;
if (shouldHardenStacks) {
try {
STACK_TRACE_HARDENING_SCRIPT.runInContext(context);
} catch {
}
}
if (isStrictOrSecure) {
try {
Object.defineProperty(context, "__ag_reportViolation__", {
value: (type) => {
if (!policyViolation.type) policyViolation.type = String(type);
},
writable: false,
configurable: false,
enumerable: false
});
CODE_GENERATION_VIOLATION_DETECTOR_SCRIPT.runInContext(context);
} catch {
}
}
const wrappedCode = "(async () => {\n" + msg.code + '\nreturn typeof __ag_main === "function" ? await __ag_main() : undefined;\n})();';
const script = new import_vm.default.Script(wrappedCode, {
filename: "agentscript.js"
});
const result = await script.runInContext(context, {
timeout: msg.config.timeout,
breakOnSigint: true
});
currentExecution.stats.endTime = Date.now();
currentExecution.stats.duration = currentExecution.stats.endTime - startTime;
if (isStrictOrSecure && policyViolation.type) {
sendMessage({
type: "result",
requestId: msg.requestId,
success: false,
error: {
name: "SecurityViolationError",
message: "Blocked operation: security policy violation",
code: "SECURITY_VIOLATION"
},
stats: currentExecution.stats
});
return;
}
sendMessage({
type: "result",
requestId: msg.requestId,
success: true,
value: sanitizeObject(result),
stats: currentExecution.stats
});
} catch (error) {
if (currentExecution) {
currentExecution.stats.endTime = Date.now();
currentExecution.stats.duration = currentExecution.stats.endTime - startTime;
}
sendMessage({
type: "result",
requestId: msg.requestId,
success: false,
error: serializeError(error, msg.config.sanitizeStackTraces),
stats: currentExecution?.stats ?? {
duration: Date.now() - startTime,
toolCallCount: 0,
iterationCount: 0,
startTime,
endTime: Date.now()
}
});
} finally {
for (const [callId, pending] of pendingToolCalls) {
if (callId.startsWith(`${msg.requestId}-`)) {
pending.reject(new Error("Execution ended"));
pendingToolCalls.delete(callId);
}
}
currentExecution = null;
}
}
function handleToolResponse(msg) {
const pending = pendingToolCalls.get(msg.callId);
if (!pending) {
console.warn("Received response for unknown tool call:", msg.callId);
return;
}
pendingToolCalls.delete(msg.callId);
if (msg.error) {
const error = new Error(msg.error.message);
error.name = msg.error.name;
pending.reject(error);
} else {
pending.resolve(sanitizeObject(msg.result));
}
}
function handleMemoryReport() {
const usage = process.memoryUsage();
sendMessage({
type: "memory-report-result",
usage: {
rss: usage.rss,
heapTotal: usage.heapTotal,
heapUsed: usage.heapUsed,
external: usage.external,
arrayBuffers: usage.arrayBuffers
}
});
}
function handleAbort(requestId) {
if (currentExecution && currentExecution.id === requestId) {
currentExecution.aborted = true;
}
for (const [callId, pending] of pendingToolCalls) {
if (callId.startsWith(`${requestId}-`)) {
pending.reject(new Error("Execution aborted"));
pendingToolCalls.delete(callId);
}
}
}
function handleTerminate(graceful) {
if (graceful && currentExecution) {
currentExecution.aborted = true;
} else {
process.exit(0);
}
}
function getGlobalValue(name, requestId, config) {
switch (name) {
case "__safe_callTool":
case "callTool":
return createProxiedCallTool(requestId, config);
case "__safe_forOf":
return createSafeForOf();
case "__safe_for":
return createSafeFor();
case "__safe_while":
case "__safe_doWhile":
return createSafeWhile();
case "__maxIterations":
return config.maxIterations ?? 1e4;
case "console":
case "__safe_console":
return createSafeConsole(requestId, config);
// Core built-in objects (always safe)
case "Math":
return Math;
case "JSON":
return JSON;
case "Object":
return Object;
case "Array":
return Array;
case "String":
return String;
case "Number":
return Number;
case "Date":
return Date;
// Safe standard globals
case "undefined":
return void 0;
case "NaN":
return NaN;
case "Infinity":
return Infinity;
// Utility functions (STANDARD level and above)
case "parseInt":
return parseInt;
case "parseFloat":
return parseFloat;
case "isNaN":
return isNaN;
case "isFinite":
return isFinite;
case "encodeURI":
return encodeURI;
case "decodeURI":
return decodeURI;
case "encodeURIComponent":
return encodeURIComponent;
case "decodeURIComponent":
return decodeURIComponent;
default:
return void 0;
}
}
function getAllowedGlobalsForSecurityLevel(securityLevel) {
const strictGlobals = [
"callTool",
"__safe_callTool",
"Math",
"JSON",
"Array",
"Object",
"String",
"Number",
"Date",
"undefined",
"NaN",
"Infinity",
"__safe_forOf",
"__safe_for",
"__safe_while",
"__safe_doWhile",
"__maxIterations"
];
const secureGlobals = [
...strictGlobals,
"parseInt",
"parseFloat",
"isNaN",
"isFinite",
"encodeURI",
"decodeURI",
"encodeURIComponent",
"decodeURIComponent"
];
const standardGlobals = [...secureGlobals];
const permissiveGlobals = [...standardGlobals, "console", "__safe_console"];
switch (securityLevel) {
case "PERMISSIVE":
return permissiveGlobals;
case "STANDARD":
return standardGlobals;
case "SECURE":
return secureGlobals;
case "STRICT":
default:
return strictGlobals;
}
}
function createSandbox(requestId, config) {
const sandbox = /* @__PURE__ */ Object.create(null);
const allowedGlobals = getAllowedGlobalsForSecurityLevel(config.securityLevel);
for (const name of allowedGlobals) {
const value = getGlobalValue(name, requestId, config);
if (value !== void 0 || name === "undefined") {
sandbox[name] = value;
}
}
if (config.globals) {
for (const [key, value] of Object.entries(config.globals)) {
if (typeof value !== "function") {
sandbox[key] = sanitizeObject(value);
}
}
}
return sandbox;
}
function createProxiedCallTool(requestId, config) {
return async function __safe_callTool(toolName, args) {
if (currentExecution?.aborted) {
throw new Error("Execution aborted");
}
if (currentExecution) {
currentExecution.stats.toolCallCount++;
}
if (currentExecution && currentExecution.stats.toolCallCount > config.maxToolCalls) {
throw new Error(
`Maximum tool call limit exceeded (${config.maxToolCalls}). This limit prevents runaway script execution.`
);
}
if (typeof toolName !== "string" || !toolName) {
throw new TypeError("Tool name must be a non-empty string");
}
if (typeof args !== "object" || args === null || Array.isArray(args)) {
throw new TypeError("Tool arguments must be an object");
}
const callId = `${requestId}-${Date.now()}-${import_crypto.default.randomUUID()}`;
return new Promise((resolve, reject) => {
pendingToolCalls.set(callId, { resolve, reject });
sendMessage({
type: "tool-call",
requestId,
callId,
toolName,
args: sanitizeObject(args)
});
});
};
}
function createSafeForOf() {
return function* __safe_forOf(iterable) {
let iterations = 0;
for (const item of iterable) {
if (currentExecution?.aborted) {
throw new Error("Execution aborted");
}
iterations++;
if (currentExecution) {
currentExecution.stats.iterationCount++;
}
const maxIterations = currentExecution?.config.maxIterations ?? 1e4;
if (iterations > maxIterations) {
throw new Error(
`Maximum iteration limit exceeded (${maxIterations}). This limit prevents infinite loops.`
);
}
yield item;
}
};
}
function createSafeFor() {
return function __safe_for(init, test, update, body) {
let iterations = 0;
init();
while (test()) {
if (currentExecution?.aborted) {
throw new Error("Execution aborted");
}
iterations++;
if (currentExecution) {
currentExecution.stats.iterationCount++;
}
const maxIterations = currentExecution?.config.maxIterations ?? 1e4;
if (iterations > maxIterations) {
throw new Error(
`Maximum iteration limit exceeded (${maxIterations}). This limit prevents infinite loops.`
);
}
body();
update();
}
};
}
function createSafeWhile() {
return function __safe_while(test, body) {
let iterations = 0;
while (test()) {
if (currentExecution?.aborted) {
throw new Error("Execution aborted");
}
iterations++;
if (currentExecution) {
currentExecution.stats.iterationCount++;
}
const maxIterations = currentExecution?.config.maxIterations ?? 1e4;
if (iterations > maxIterations) {
throw new Error(
`Maximum iteration limit exceeded (${maxIterations}). This limit prevents infinite loops.`
);
}
body();
}
};
}
function createSafeConsole(requestId, config) {
let totalBytes = 0;
let callCount = 0;
function safeLog(level, args) {
callCount++;
if (callCount > config.maxConsoleCalls) {
throw new Error(`Console call limit exceeded (${config.maxConsoleCalls})`);
}
const serialized = args.map((a) => {
try {
return JSON.stringify(sanitizeObject(a));
} catch {
return String(a);
}
});
const bytes = serialized.reduce((sum, s) => sum + (s?.length ?? 0), 0);
totalBytes += bytes;
if (totalBytes > config.maxConsoleOutputBytes) {
throw new Error(`Console output limit exceeded (${config.maxConsoleOutputBytes} bytes)`);
}
sendMessage({
type: "console",
requestId,
level,
args: serialized
});
}
return {
log: (...args) => safeLog("log", args),
warn: (...args) => safeLog("warn", args),
error: (...args) => safeLog("error", args),
info: (...args) => safeLog("info", args)
};
}
function sendMessage(msg) {
if (!port) {
throw new Error("Worker port not initialized");
}
port.postMessage(safeSerialize(msg));
}
function serializeError(error, sanitizeStackTraces) {
if (typeof error === "string") {
return { name: "Error", message: error };
}
const err = error;
const serialized = {
name: err.name || "Error",
message: err.message || "Unknown error"
};
if (err.code) {
serialized.code = err.code;
}
if (err.stack && !sanitizeStackTraces) {
serialized.stack = err.stack;
} else if (err.stack && sanitizeStackTraces) {
serialized.stack = err.stack.split("\n").slice(0, 5).map((line) => line.replace(/\(.*?:\d+:\d+\)/g, "(...)")).join("\n");
}
return serialized;
}
sendMessage({ type: "ready" });
+1
-0

@@ -30,2 +30,3 @@ /**

private initialized;
private readonly boundMemoryExceededHandler;
private _totalExecutions;

@@ -32,0 +33,0 @@ private _successfulExecutions;

@@ -51,2 +51,3 @@ /**

private readonly doubleVmConfig;
private readonly customGlobalNames;
private adapter?;

@@ -53,0 +54,0 @@ constructor(options?: CreateEnclaveOptions);

+5
-5
{
"name": "@enclave-vm/core",
"version": "2.10.0",
"version": "2.10.1",
"description": "Sandbox runtime for secure JavaScript code execution",

@@ -40,9 +40,9 @@ "author": "AgentFront <info@agentfront.dev>",

"dependencies": {
"@babel/standalone": "^7.28.6",
"@enclave-vm/types": "2.10.0",
"@enclave-vm/ast": "2.10.0",
"@babel/standalone": "^7.29.0",
"@enclave-vm/types": "2.10.1",
"@enclave-vm/ast": "2.10.1",
"acorn": "8.15.0",
"acorn-walk": "8.3.4",
"astring": "1.9.0",
"zod": "^4.1.13"
"zod": "^4.3.6"
},

@@ -49,0 +49,0 @@ "peerDependencies": {

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display