Skip to content

Commit 9c4325b

Browse files
authored
fix(core): don't permit access to system directories (anomalyco#16891)
1 parent ad08fd5 commit 9c4325b

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

packages/opencode/src/file/index.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Ripgrep } from "./ripgrep"
1111
import fuzzysort from "fuzzysort"
1212
import { Global } from "../global"
1313
import { git } from "@/util/git"
14+
import { Protected } from "./protected"
1415

1516
export namespace File {
1617
const log = Log.create({ service: "file" })
@@ -345,10 +346,7 @@ export namespace File {
345346

346347
if (isGlobalHome) {
347348
const dirs = new Set<string>()
348-
const ignore = new Set<string>()
349-
350-
if (process.platform === "darwin") ignore.add("Library")
351-
if (process.platform === "win32") ignore.add("AppData")
349+
const ignore = Protected.names()
352350

353351
const ignoreNested = new Set(["node_modules", "dist", "build", "target", "vendor"])
354352
const shouldIgnore = (name: string) => name.startsWith(".") || ignore.has(name)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import path from "path"
2+
import os from "os"
3+
4+
const home = os.homedir()
5+
6+
// macOS directories that trigger TCC (Transparency, Consent, and Control)
7+
// permission prompts when accessed by a non-sandboxed process.
8+
const DARWIN_HOME = [
9+
// Media
10+
"Music",
11+
"Pictures",
12+
"Movies",
13+
// User-managed folders synced via iCloud / subject to TCC
14+
"Downloads",
15+
"Desktop",
16+
"Documents",
17+
// Other system-managed
18+
"Public",
19+
"Applications",
20+
"Library",
21+
]
22+
23+
const DARWIN_LIBRARY = [
24+
"Application Support/AddressBook",
25+
"Calendars",
26+
"Mail",
27+
"Messages",
28+
"Safari",
29+
"Cookies",
30+
"Application Support/com.apple.TCC",
31+
"PersonalizationPortrait",
32+
"Metadata/CoreSpotlight",
33+
"Suggestions",
34+
]
35+
36+
const DARWIN_ROOT = ["/.DocumentRevisions-V100", "/.Spotlight-V100", "/.Trashes", "/.fseventsd"]
37+
38+
const WIN32_HOME = ["AppData", "Downloads", "Desktop", "Documents", "Pictures", "Music", "Videos", "OneDrive"]
39+
40+
export namespace Protected {
41+
/** Directory basenames to skip when scanning the home directory. */
42+
export function names(): ReadonlySet<string> {
43+
if (process.platform === "darwin") return new Set(DARWIN_HOME)
44+
if (process.platform === "win32") return new Set(WIN32_HOME)
45+
return new Set()
46+
}
47+
48+
/** Absolute paths that should never be watched, stated, or scanned. */
49+
export function paths(): string[] {
50+
if (process.platform === "darwin")
51+
return [
52+
...DARWIN_HOME.map((n) => path.join(home, n)),
53+
...DARWIN_LIBRARY.map((n) => path.join(home, "Library", n)),
54+
...DARWIN_ROOT,
55+
]
56+
if (process.platform === "win32") return WIN32_HOME.map((n) => path.join(home, n))
57+
return []
58+
}
59+
}

packages/opencode/src/file/watcher.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type ParcelWatcher from "@parcel/watcher"
1414
import { Flag } from "@/flag/flag"
1515
import { readdir } from "fs/promises"
1616
import { git } from "@/util/git"
17+
import { Protected } from "./protected"
1718

1819
const SUBSCRIBE_TIMEOUT_MS = 10_000
1920

@@ -76,7 +77,7 @@ export namespace FileWatcher {
7677

7778
if (Flag.OPENCODE_EXPERIMENTAL_FILEWATCHER) {
7879
const pending = w.subscribe(Instance.directory, subscribe, {
79-
ignore: [...FileIgnore.PATTERNS, ...cfgIgnores],
80+
ignore: [...FileIgnore.PATTERNS, ...cfgIgnores, ...Protected.paths()],
8081
backend,
8182
})
8283
const sub = await withTimeout(pending, SUBSCRIBE_TIMEOUT_MS).catch((err) => {

0 commit comments

Comments
 (0)