跳到主要内容

路径验证

源码: tools/PathValidation.ts | utils/paths.ts

1. 路径验证目的

确保 Claude Code 只能操作项目目录内的文件,防止意外修改系统文件或其他项目。

2. 验证机制

// 获取项目根目录
function getProjectRoot(): string {
// 1. 检查 .claude 目录
// 2. 回退到 git 根目录
// 3. 回退到当前工作目录
return resolveProjectRoot()
}

// 验证路径是否在项目范围内
function isPathAllowed(targetPath: string): boolean {
const root = getProjectRoot()
const resolved = path.resolve(root, targetPath)
return resolved.startsWith(root + '/') || resolved === root
}

3. 目录遍历保护

// 防御目录遍历攻击
function sanitizePath(input: string): string {
// 1. 规范化路径(解析 ../, ./, //)
const normalized = path.normalize(input)

// 2. 解析符号链接
const resolved = path.resolve(getProjectRoot(), normalized)

// 3. 检查是否逃逸项目目录
if (!resolved.startsWith(getProjectRoot())) {
throw new Error('路径超出项目范围')
}

return resolved
}

4. 符号链接处理

// 安全地跟随符号链接
async function safeResolveSymlink(linkPath: string): Promise<string> {
const stat = await fs.lstat(linkPath)

if (stat.isSymbolicLink()) {
const target = await fs.readlink(linkPath)
const resolved = path.resolve(path.dirname(linkPath), target)

// 验证符号链接目标也在项目目录内
if (!resolved.startsWith(getProjectRoot())) {
throw new Error('符号链接指向项目外部')
}

return resolved
}

return linkPath
}

5. 文件工具的路径检查

所有文件操作工具在调用前都经过路径验证:

// FileReadTool
async function call(input: FileReadInput) {
const safePath = sanitizePath(input.path)
// 安全检查通过后才读取
const content = await fs.readFile(safePath, 'utf-8')
return { content }
}

// FileWriteTool
async function call(input: FileWriteInput) {
const safePath = sanitizePath(input.path)
// 安全检查通过后才写入
await fs.writeFile(safePath, input.content)
return { success: true }
}

6. 特殊路径处理

路径处理方式
~展开为用户 HOME 目录,通常禁止访问
../规范化后检查是否越界
/tmp临时目录通常允许
.env包含密钥的文件,特殊保护

上一节:权限控制 | 下一节:策略限制