- commit
- 15928cd
- parent
- 50e7bf8
- author
- im_wower
- date
- 2026-03-30 00:04:35 +0800 CST
fix: block .git paths in code file serving
2 files changed,
+22,
-8
+20,
-1
1@@ -4407,7 +4407,6 @@ test("handleConductorHttpRequest serves code files and blocks unsafe paths", asy
2 );
3 assert.equal(directoryResponse.status, 200);
4 assert.deepEqual(Buffer.from(directoryResponse.body).toString("utf8").split("\n"), [
5- ".git",
6 "package.json",
7 "src"
8 ]);
9@@ -4442,6 +4441,26 @@ test("handleConductorHttpRequest serves code files and blocks unsafe paths", asy
10 assert.equal(hiddenGitObjectsResponse.status, 403);
11 assert.equal(parseJsonBody(hiddenGitObjectsResponse).error, "forbidden");
12
13+ const hiddenGitConfigResponse = await handleConductorHttpRequest(
14+ {
15+ method: "GET",
16+ path: "/code/demo-repo/.git/config"
17+ },
18+ context
19+ );
20+ assert.equal(hiddenGitConfigResponse.status, 403);
21+ assert.equal(parseJsonBody(hiddenGitConfigResponse).error, "forbidden");
22+
23+ const hiddenGitDirectoryResponse = await handleConductorHttpRequest(
24+ {
25+ method: "GET",
26+ path: "/code/demo-repo/.git"
27+ },
28+ context
29+ );
30+ assert.equal(hiddenGitDirectoryResponse.status, 403);
31+ assert.equal(parseJsonBody(hiddenGitDirectoryResponse).error, "forbidden");
32+
33 const traversalResponse = await handleConductorHttpRequest(
34 {
35 method: "GET",
1@@ -120,6 +120,7 @@ const SSE_RESPONSE_HEADERS = {
2 } as const;
3 const ALLOWED_ARTIFACT_SCOPES = new Set(["exec", "msg", "session"]);
4 const BLOCKED_CODE_FILE_NAMES = new Set([".credentials", ".env"]);
5+const BLOCKED_CODE_PATH_SEGMENTS = new Set([".git"]);
6 const BLOCKED_CODE_BINARY_EXTENSIONS = new Set([
7 ".7z",
8 ".a",
9@@ -5888,16 +5889,10 @@ function isBlockedCodePath(relativePath: string): boolean {
10 const normalized = normalizeCodeRelativePath(relativePath);
11 const segments = normalized === "" ? [] : normalized.split("/");
12
13- if (segments.some((segment) => BLOCKED_CODE_FILE_NAMES.has(segment))) {
14+ if (segments.some((segment) => BLOCKED_CODE_FILE_NAMES.has(segment) || BLOCKED_CODE_PATH_SEGMENTS.has(segment))) {
15 return true;
16 }
17
18- for (let index = 0; index < segments.length - 1; index += 1) {
19- if (segments[index] === ".git" && segments[index + 1] === "objects") {
20- return true;
21- }
22- }
23-
24 return false;
25 }
26