better guarding against bash commands that go outside of cwd

This commit is contained in:
Dax Raad
2025-07-31 21:41:48 -04:00
parent 44211e1526
commit b6ee8e92f9
2 changed files with 8 additions and 6 deletions

View File

@@ -5,15 +5,17 @@ import { App } from "../app/app"
import { Permission } from "../permission" import { Permission } from "../permission"
import { Config } from "../config/config" import { Config } from "../config/config"
import { Filesystem } from "../util/filesystem" import { Filesystem } from "../util/filesystem"
import path from "path"
import { lazy } from "../util/lazy" import { lazy } from "../util/lazy"
import { Log } from "../util/log" import { Log } from "../util/log"
import { Wildcard } from "../util/wildcard" import { Wildcard } from "../util/wildcard"
import { $ } from "bun"
const MAX_OUTPUT_LENGTH = 30000 const MAX_OUTPUT_LENGTH = 30000
const DEFAULT_TIMEOUT = 1 * 60 * 1000 const DEFAULT_TIMEOUT = 1 * 60 * 1000
const MAX_TIMEOUT = 10 * 60 * 1000 const MAX_TIMEOUT = 10 * 60 * 1000
const log = Log.create({ service: "bash-tool" })
const parser = lazy(async () => { const parser = lazy(async () => {
const { default: Parser } = await import("tree-sitter") const { default: Parser } = await import("tree-sitter")
const Bash = await import("tree-sitter-bash") const Bash = await import("tree-sitter-bash")
@@ -73,7 +75,8 @@ export const BashTool = Tool.define("bash", {
if (["cd", "rm", "cp", "mv", "mkdir", "touch", "chmod", "chown"].includes(command[0])) { if (["cd", "rm", "cp", "mv", "mkdir", "touch", "chmod", "chown"].includes(command[0])) {
for (const arg of command.slice(1)) { for (const arg of command.slice(1)) {
if (arg.startsWith("-")) continue if (arg.startsWith("-")) continue
const resolved = path.resolve(app.path.cwd, arg) const resolved = await $`realpath ${arg}`.text().then((x) => x.trim())
log.info("resolved path", { arg, resolved })
if (!Filesystem.contains(app.path.cwd, resolved)) { if (!Filesystem.contains(app.path.cwd, resolved)) {
throw new Error( throw new Error(
`This command references paths outside of ${app.path.cwd} so it is not allowed to be executed.`, `This command references paths outside of ${app.path.cwd} so it is not allowed to be executed.`,
@@ -87,10 +90,8 @@ export const BashTool = Tool.define("bash", {
const ask = (() => { const ask = (() => {
for (const [pattern, value] of Object.entries(permissions)) { for (const [pattern, value] of Object.entries(permissions)) {
const match = Wildcard.match(node.text, pattern) const match = Wildcard.match(node.text, pattern)
Log.Default.info("checking", { text: node.text, pattern, match }) log.info("checking", { text: node.text.trim(), pattern, match })
if (match) { if (match) return value
return value
}
} }
return "ask" return "ask"
})() })()

View File

@@ -7,6 +7,7 @@ export namespace Wildcard {
.replace(/\*/g, ".*") // * becomes .* .replace(/\*/g, ".*") // * becomes .*
.replace(/\?/g, ".") + // ? becomes . .replace(/\?/g, ".") + // ? becomes .
"$", "$",
"s", // s flag enables multiline matching
) )
return regex.test(str) return regex.test(str)
} }