跳转至

Deep Dive | src/tools/PowerShellTool/pathValidation.ts 2049 行 — PowerShell 路径校验

重要性:⭐⭐⭐(PowerShell 工具安全——路径约束检查、危险路径检测、glob 处理) 真实位置src/tools/PowerShellTool/pathValidation.ts2049 行角色:PowerShell 命令的路径校验——allowed / denied 规则、危险删除检测、glob 展开 关联topics/deep-dive-bash-permissions.md(Bash 权限)、PowerShell 工具


1. 文件全景

pathValidation.ts (2049 行)
├── 行 1-90   :imports + 常量 + 3 个 Type
│   ├── MAX_DIRS_TO_LIST (5)
│   ├── GLOB_PATTERN_REGEX
│   ├── FileOperationType (read/write/create)
│   ├── PathCheckResult
│   ├── ResolvedPathCheckResult
│   └── CmdletPathConfig (行 88, ~680 行 — 巨大)
├── 行 772-870:5 个 helper
│   ├── matchesParam (行 772, ~20 行)
│   ├── hasComplexColonValue (行 793, ~12 行)
│   ├── formatDirectoryList (行 805, ~15 行)
│   ├── expandTilde (行 820, ~20 行)
│   ├── isDangerousRemovalRawPath (export, 行 840, ~8 行)
│   └── dangerousRemovalDeny (export, 行 848, ~15 行)
├── 行 863-1265:**isPathAllowed + validatePath (~400 行)**
│   ├── isPathAllowed (行 863, ~120 行)
│   ├── checkDenyRuleForGuessedPath (行 984, ~30 行)
│   └── validatePath (行 1013, ~250 行)
├── 行 1266-1305:glob helpers
│   ├── getGlobBaseDirectory (行 1266, ~30 行)
│   ├── SAFE_PATH_ELEMENT_TYPES
│   └── extractPathsFromCommand (行 1304, ~225 行)
└── 行 1528-2049:checkPathConstraints (export, 行 1528) + checkPathConstraintsForStatement

核心洞察CmdletPathConfig 680 行——配置文件占据 33% 的文件。


2. 6 个 Type

type FileOperationType = 'read' | 'write' | 'create'
type PathCheckResult = { ... }
type ResolvedPathCheckResult = PathCheckResult & { ... }
type CmdletPathConfig = { ... }  // 680 行!

6 个 type —— 3 个操作 + 3 个结果 + 1 个配置。


3. CmdletPathConfig — 680 行(行 88-772)

type CmdletPathConfig = {
  // PowerShell cmdlet 路径约束配置
  // 680 行 - 巨大配置
}

680 行 —— 单个 type 占据 33% 文件。

为什么这么大: - PowerShell 有 50+ cmdlet 接受路径 - 每个 cmdlet 不同的 -Path / -LiteralPath / -FilePath 参数 - 每个 cmdlet 不同行为


4. matchesParam — 20 行(行 772)

function matchesParam(paramLower: string, paramList: string[]): boolean {
  // 参数名匹配
}

20 行 —— 检查 -Path / -LiteralPath 等。


5. hasComplexColonValue — 12 行(行 793)

function hasComplexColonValue(rawValue: string): boolean {
  // 检查冒号值(PowerShell switch 语法)
}

PowerShell switch 语法 —— -Path:foo-Path foo 等价。


6. formatDirectoryList — 15 行(行 805)

function formatDirectoryList(directories: string[]): string {
  // 格式化目录列表(错误信息)
}

15 行 —— 友好错误。


7. expandTilde — 20 行(行 820)

function expandTilde(filePath: string): string {
  // ~ → $HOME
}

20 行 —— ~/foo 展开。


8. isDangerousRemovalRawPath + dangerousRemovalDeny — 23 行(行 840, 848)

export function isDangerousRemovalRawPath(filePath: string): boolean {
  // 检测危险删除路径(rm -rf / 等)
}

export function dangerousRemovalDeny(path: string): PermissionResult {
  // 返回 deny 决策
}

2 个 export —— 危险路径检测。

危险模式: - * 单独(删所有) - /* 根目录 - ~/.../* home 全部 - . 当前目录递归 - .. 父目录


9. isPathAllowed — 120 行(行 863)

function isPathAllowed(filePath: string, config: ...): boolean {
  // 1. 解析 ~
  // 2. 检查 allowlist
  // 3. 检查 denylist
  // 4. glob 展开检查
}

120 行 —— 路径 allow/deny 检查。


10. checkDenyRuleForGuessedPath — 30 行(行 984)

function checkDenyRuleForGuessedPath(path, config): PermissionResult {
  // 猜测的路径(命令未明确指定)deny
}

30 行 —— 保守 deny 未明确路径。


11. validatePath — 250 行(行 1013)

function validatePath(filePath: string, config: ...): PathCheckResult {
  // 1. 解析 ~ 和 ./
  // 2. 解析通配符
  // 3. 检查 allowlist
  // 4. 检查 denylist
  // 5. 危险检测
  // 6. 返回结果
}

250 行 —— 单路径完整校验。


12. getGlobBaseDirectory — 30 行(行 1266)

function getGlobBaseDirectory(filePath: string): string {
  // 提取 glob 的基础目录
}

30 行 —— src/*.tssrc/


13. extractPathsFromCommand — 225 行(行 1304)

function extractPathsFromCommand(cmd: ParsedCommandElement): string[] {
  // 从 PowerShell AST 提取所有路径
}

225 行 —— 解析 PowerShell AST 找所有路径。


14. checkPathConstraints (export) + checkPathConstraintsForStatement(行 1528, 1569)

export function checkPathConstraints(...): PermissionResult {
  // 顶层
}

function checkPathConstraintsForStatement(...): PermissionResult {
  // 单语句
}

2 个入口 —— 命令 / 语句粒度。


15. 关键设计模式

15.1 680 行 CmdletPathConfig

巨大配置 —— 50+ cmdlet × 多参数。

15.2 危险路径白/黑名单

isDangerousRemovalRawPath —— rm -rf / 类攻击防御。

15.3 glob 展开

getGlobBaseDirectory —— 不展开通配符,只检查 base dir。

15.4 ~ 展开

expandTilde —— ~/foo$HOME/foo

15.5 PowerShell switch 语法

hasComplexColonValue —— -Path:foo 特殊处理。

15.6 保守 deny

checkDenyRuleForGuessedPath —— 未明确路径 = deny

15.7 AST 路径提取

extractPathsFromCommand —— 从 PowerShell AST 找路径。

15.8 MAX_DIRS_TO_LIST = 5

5 个目录 —— 错误信息列出的上限。


16. 复杂度分析

维度 数字
总行数 2049
Type 6
公开函数 4
私有函数 8+
CmdletPathConfig 680 行
validatePath 250 行
extractPathsFromCommand 225 行

17. 与其他文件的关系

pathValidation.ts
  ├──→ PowerShell AST
  ├──→ settings (allow/deny list)
  ├──→ fs (expandTilde)
  └──→ PowerShellTool (调用)

18. 关键洞察

18.1 680 行 CmdletPathConfig 是"配置驱动"

不写死每个 cmdlet —— 集中配置管理。

18.2 危险路径检测是"安全核心"

rm -rf / 类攻击必须早期拒绝

18.3 glob 不展开 = 性能

只检查 base dir —— 避免展开 10000 文件。

18.4 保守 deny 是"安全哲学"

未明确路径 = deny —— 零信任

18.5 PowerShell switch 语法

-Path:foo 是 PowerShell 特有 —— 必须支持。

18.6 MAX_DIRS_TO_LIST = 5 是"UX"

错误信息不列 100 个目录 —— 5 个足够

18.7 250 行 validatePath 是"完整检查"

单路径 → allow/deny + 详细 reason。


19. 阅读建议

  1. 看 CmdletPathConfig 680 行(行 88)—— 配置
  2. 看 isDangerousRemovalRawPath(行 840)—— 危险检测
  3. 看 validatePath(行 1013)—— 单路径校验
  4. 看 extractPathsFromCommand(行 1304)—— AST 提取
  5. 看 checkPathConstraints(行 1528)—— 入口

20. 与其他深度拆解的关系

文件 关系
bashPermissions.ts Bash 路径校验(对比)
PowerShellTool/ 调用
settings allow/deny 来源

21. 阅读清单

  1. ✅ 看 CmdletPathConfig(行 88)
  2. ✅ 看 isDangerousRemovalRawPath(行 840)
  3. ✅ 看 validatePath(行 1013)
  4. ✅ 看 extractPathsFromCommand(行 1304)
  5. ✅ 看 checkPathConstraints(行 1528)

22. 练习任务

  1. 数危险路径(grep isDangerousRemovalRawPath
  2. 数 cmdlet 配置(grep in CmdletPathConfig)—— 50+
  3. 画校验流程 —— 输入路径 → 解析 → 检查 → 决策
  4. 手写迷你 pathValidation(~50 行)—— 1 个 denylist 检查
  5. 思考:PowerShell vs Bash 路径校验的差异?