Harden session discovery with path validation and parallel I/O
Security: Reject session paths containing '..' traversal segments or non-.jsonl extensions before resolving them. This prevents a malicious sessions-index.json from tricking the viewer into reading arbitrary files. Performance: Process all project directories concurrently with Promise.all instead of sequentially awaiting each one. Each directory's stat + readFile is independent I/O that benefits from parallelism. Add test case verifying that traversal paths and non-JSONL paths are rejected while valid paths pass through. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -111,6 +111,42 @@ describe("session-discovery", () => {
|
||||
await fs.rm(tmpDir, { recursive: true });
|
||||
});
|
||||
|
||||
it("rejects paths with traversal segments", async () => {
|
||||
const tmpDir = path.join(os.tmpdir(), `sv-test-traversal-${Date.now()}`);
|
||||
const projectDir = path.join(tmpDir, "traversal-project");
|
||||
await fs.mkdir(projectDir, { recursive: true });
|
||||
|
||||
await fs.writeFile(
|
||||
path.join(projectDir, "sessions-index.json"),
|
||||
makeIndex([
|
||||
{
|
||||
sessionId: "evil-001",
|
||||
fullPath: "/home/ubuntu/../../../etc/passwd",
|
||||
created: "2025-10-15T10:00:00Z",
|
||||
modified: "2025-10-15T11:00:00Z",
|
||||
},
|
||||
{
|
||||
sessionId: "evil-002",
|
||||
fullPath: "/home/ubuntu/sessions/not-a-jsonl.txt",
|
||||
created: "2025-10-15T10:00:00Z",
|
||||
modified: "2025-10-15T11:00:00Z",
|
||||
},
|
||||
{
|
||||
sessionId: "good-001",
|
||||
fullPath: "/home/ubuntu/.claude/projects/xyz/good-001.jsonl",
|
||||
created: "2025-10-15T10:00:00Z",
|
||||
modified: "2025-10-15T11:00:00Z",
|
||||
},
|
||||
])
|
||||
);
|
||||
|
||||
const sessions = await discoverSessions(tmpDir);
|
||||
expect(sessions).toHaveLength(1);
|
||||
expect(sessions[0].id).toBe("good-001");
|
||||
|
||||
await fs.rm(tmpDir, { recursive: true });
|
||||
});
|
||||
|
||||
it("uses fullPath from index entry", async () => {
|
||||
const tmpDir = path.join(os.tmpdir(), `sv-test-fp-${Date.now()}`);
|
||||
const projectDir = path.join(tmpDir, "fp-project");
|
||||
|
||||
Reference in New Issue
Block a user