diff --git a/src/cognition/emergent/SandboxedToolForge.ts b/src/cognition/emergent/SandboxedToolForge.ts index 3731cace1d0..c0db5a0e453 100644 --- a/src/cognition/emergent/SandboxedToolForge.ts +++ b/src/cognition/emergent/SandboxedToolForge.ts @@ -33,7 +33,7 @@ */ import { createHash, createHmac, randomUUID } from 'node:crypto'; -import { readFile } from 'node:fs/promises'; +import { readFile, realpath } from 'node:fs/promises'; import * as path from 'node:path'; import type { SandboxExecutionRequest, SandboxExecutionResult, SandboxAPI } from './types.js'; import { CodeSandbox } from '../../safety/sandbox/executor/CodeSandbox.js'; @@ -474,7 +474,7 @@ export class SandboxedToolForge { if (allowlist.includes('fs.readFile')) { extras.fs = { readFile: async (filePath: string) => { - const resolvedPath = path.resolve(filePath); + const resolvedPath = await realpath(path.resolve(filePath)); const allowed = this.fsReadRoots.some((root) => { return resolvedPath === root || resolvedPath.startsWith(`${root}${path.sep}`); }); @@ -483,7 +483,7 @@ export class SandboxedToolForge { `fs.readFile blocked: path "${resolvedPath}" is outside the allowed roots`, ); } - const data = await readFile(filePath); + const data = await readFile(resolvedPath); if (data.byteLength > 1_048_576) { throw new Error( `fs.readFile blocked: file exceeds 1 MB limit (${data.byteLength} bytes)`,