diff options
| author | Adam Malczewski <[email protected]> | 2026-06-21 23:32:23 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-21 23:32:23 +0900 |
| commit | 7f6fd218ceeb3a1cf9420f5f6cfa4d70da6987bb (patch) | |
| tree | e706f49d2df591c468fb66febe2a3f29d23cb0bb /packages/tool-write-file/src/write-file.test.ts | |
| parent | 62ea07f56ff066bbf05041aadf8006cbc65e5c53 (diff) | |
| download | dispatch-7f6fd218ceeb3a1cf9420f5f6cfa4d70da6987bb.tar.gz dispatch-7f6fd218ceeb3a1cf9420f5f6cfa4d70da6987bb.zip | |
feat: remove CWD path containment from file tools
read_file, write_file, and edit_file no longer restrict access to
paths outside the working directory. The isPathWithinWorkdir prefix
check and symlink hardening have been removed from all three tools.
This allows agents to read and write files anywhere on the filesystem,
not just within the per-turn cwd. The shell tool already had no such
restriction.
Diffstat (limited to 'packages/tool-write-file/src/write-file.test.ts')
| -rw-r--r-- | packages/tool-write-file/src/write-file.test.ts | 60 |
1 files changed, 2 insertions, 58 deletions
diff --git a/packages/tool-write-file/src/write-file.test.ts b/packages/tool-write-file/src/write-file.test.ts index cf4fa64..6b316bc 100644 --- a/packages/tool-write-file/src/write-file.test.ts +++ b/packages/tool-write-file/src/write-file.test.ts @@ -3,12 +3,7 @@ import { tmpdir } from "node:os"; import { join } from "node:path"; import { createLogger, type ToolExecuteContext } from "@dispatch/kernel"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; -import { - createWriteFileTool, - decideOverwrite, - isPathWithinWorkdir, - validateArgs, -} from "./write-file.js"; +import { createWriteFileTool, decideOverwrite, validateArgs } from "./write-file.js"; function stubCtx(overrides?: Partial<ToolExecuteContext>): ToolExecuteContext { return { @@ -75,24 +70,6 @@ describe("decideOverwrite", () => { }); }); -describe("isPathWithinWorkdir", () => { - it("accepts a path within workdir", () => { - expect(isPathWithinWorkdir("/tmp/workdir/file.txt", "/tmp/workdir")).toBe(true); - }); - - it("accepts the workdir itself", () => { - expect(isPathWithinWorkdir("/tmp/workdir", "/tmp/workdir")).toBe(true); - }); - - it("rejects a path outside workdir", () => { - expect(isPathWithinWorkdir("/tmp/other/file.txt", "/tmp/workdir")).toBe(false); - }); - - it("rejects a prefix attack (workdir prefix but different dir)", () => { - expect(isPathWithinWorkdir("/tmp/workdir-evil/file.txt", "/tmp/workdir")).toBe(false); - }); -}); - describe("validateArgs", () => { it("returns validated args for valid input", () => { const result = validateArgs({ path: "foo.txt", content: "hello" }); @@ -192,23 +169,7 @@ describe("createWriteFileTool", () => { const result = await tool.execute({ path: "no/such/dir/file.txt", content: "data" }, stubCtx()); expect(result.isError).toBe(true); - expect(result.content).toContain("Parent directory"); - }); - - it("rejects a path outside the working directory", async () => { - const tool = createWriteFileTool(workdir); - const result = await tool.execute({ path: "../escape.txt", content: "data" }, stubCtx()); - - expect(result.isError).toBe(true); - expect(result.content).toContain("outside the working directory"); - }); - - it("rejects an absolute path outside workdir", async () => { - const tool = createWriteFileTool(workdir); - const result = await tool.execute({ path: "/tmp/escape.txt", content: "data" }, stubCtx()); - - expect(result.isError).toBe(true); - expect(result.content).toContain("outside the working directory"); + expect(result.content).toContain("Error"); }); it("concurrencySafe is false", () => { @@ -253,23 +214,6 @@ describe("createWriteFileTool", () => { } }); - it("handles symlink escape attempt", async () => { - const outsideDir = await mkdtemp(join(tmpdir(), "outside-")); - try { - const symlinkPath = join(workdir, "link.txt"); - const { symlink } = await import("node:fs/promises"); - await symlink(join(outsideDir, "target.txt"), symlinkPath); - - const tool = createWriteFileTool(workdir); - const result = await tool.execute({ path: "link.txt", content: "escape" }, stubCtx()); - - expect(result.isError).toBe(true); - expect(result.content).toContain("outside the working directory"); - } finally { - await rm(outsideDir, { recursive: true, force: true }); - } - }); - it("writes empty content", async () => { const tool = createWriteFileTool(workdir); const result = await tool.execute({ path: "empty.txt", content: "" }, stubCtx()); |
