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