Skip to content

Commit 5754bb6

Browse files
committed
Further add safe resolve in workspace
1 parent 06661eb commit 5754bb6

File tree

1 file changed

+18
-9
lines changed
  • remote-workspace/src/servers/api-server/platform-api

1 file changed

+18
-9
lines changed

remote-workspace/src/servers/api-server/platform-api/handler.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import path from "path";
44

55
// Define a safe root directory for projects. Can be overridden by env or configured as needed.
66
// All incoming URIs will be resolved and validated to ensure they don't escape this root.
7-
const SAFE_ROOT = path.resolve(process.env.PLATFORM_API_ROOT ?? "/pulse-editor");
7+
const SAFE_ROOT = path.resolve(
8+
process.env.PLATFORM_API_ROOT ?? "/pulse-editor",
9+
);
810

911
const settingsPath = path.join(SAFE_ROOT, "settings.json");
1012

@@ -14,14 +16,22 @@ function safeResolve(uri: string): string {
1416
}
1517

1618
// Resolve the input and the safe root to absolute, normalized paths.
17-
const resolved = path.resolve(uri);
18-
const root = SAFE_ROOT;
19-
20-
const relative = path.relative(root, resolved);
19+
// Always resolve relative to SAFE_ROOT (do not trust 'uri' alone)
20+
const candidate = path.resolve(SAFE_ROOT, uri);
21+
let rootReal, candidateReal;
22+
try {
23+
rootReal = fs.realpathSync(SAFE_ROOT);
24+
candidateReal = fs.realpathSync(candidate);
25+
} catch (e) {
26+
throw new Error("Path does not exist or cannot be accessed");
27+
}
2128

22-
// If the relative path starts with '..' or is absolute, it escapes the SAFE_ROOT.
23-
if (relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative))) {
24-
return resolved;
29+
// Check that candidateReal is strictly under rootReal (or equal to rootReal)
30+
if (
31+
candidateReal === rootReal ||
32+
candidateReal.startsWith(rootReal + path.sep)
33+
) {
34+
return candidateReal;
2535
}
2636

2737
throw new Error("Can only access paths within the project home directory.");
@@ -131,7 +141,6 @@ export async function handlePlatformAPIRequest(
131141
}
132142
}
133143

134-
135144
// List all folders in a path
136145
async function handleListProjects(uri: string) {
137146
const rootPath = safeResolve(uri);

0 commit comments

Comments
 (0)