* Check if a file path is dangerous to auto-edit without explicit permission. * This includes: * - Files in .git directories or .gitconfig files (to prevent git-based data exfiltration and code execution) * - Files in .vscode directories (to prevent VS Code settings manipulation and potential cod
(path: string)
| 433 | * - UNC paths (to prevent network file access and WebDAV attacks) |
| 434 | */ |
| 435 | function isDangerousFilePathToAutoEdit(path: string): boolean { |
| 436 | const absolutePath = expandPath(path) |
| 437 | const pathSegments = absolutePath.split(sep) |
| 438 | const fileName = pathSegments.at(-1) |
| 439 | |
| 440 | // Check for UNC paths (defense-in-depth to catch any patterns that might not be caught by containsVulnerableUncPath) |
| 441 | // Block anything starting with \\ or // as these are potentially UNC paths that could access network resources |
| 442 | if (path.startsWith('\\\\') || path.startsWith('//')) { |
| 443 | return true |
| 444 | } |
| 445 | |
| 446 | // Check if path is within dangerous directories (case-insensitive to prevent bypasses) |
| 447 | for (let i = 0; i < pathSegments.length; i++) { |
| 448 | const segment = pathSegments[i]! |
| 449 | const normalizedSegment = normalizeCaseForComparison(segment) |
| 450 | |
| 451 | for (const dir of DANGEROUS_DIRECTORIES) { |
| 452 | if (normalizedSegment !== normalizeCaseForComparison(dir)) { |
| 453 | continue |
| 454 | } |
| 455 | |
| 456 | // Special case: .claude/worktrees/ is a structural path (where Claude stores |
| 457 | // git worktrees), not a user-created dangerous directory. Skip the .claude |
| 458 | // segment when it's followed by 'worktrees'. Any nested .claude directories |
| 459 | // within the worktree (not followed by 'worktrees') are still blocked. |
| 460 | if (dir === '.claude') { |
| 461 | const nextSegment = pathSegments[i + 1] |
| 462 | if ( |
| 463 | nextSegment && |
| 464 | normalizeCaseForComparison(nextSegment) === 'worktrees' |
| 465 | ) { |
| 466 | break // Skip this .claude, continue checking other segments |
| 467 | } |
| 468 | } |
| 469 | |
| 470 | return true |
| 471 | } |
| 472 | } |
| 473 | |
| 474 | // Check for dangerous configuration files (case-insensitive) |
| 475 | if (fileName) { |
| 476 | const normalizedFileName = normalizeCaseForComparison(fileName) |
| 477 | if ( |
| 478 | (DANGEROUS_FILES as readonly string[]).some( |
| 479 | dangerousFile => |
| 480 | normalizeCaseForComparison(dangerousFile) === normalizedFileName, |
| 481 | ) |
| 482 | ) { |
| 483 | return true |
| 484 | } |
| 485 | } |
| 486 | |
| 487 | return false |
| 488 | } |
| 489 | |
| 490 | /** |
| 491 | * Detects suspicious Windows path patterns that could bypass security checks. |
no test coverage detected