MCPcopy
hub / github.com/codeaashu/claude-code / checkReadPermissionForTool

Function checkReadPermissionForTool

src/utils/permissions/filesystem.ts:1030–1194  ·  view source on GitHub ↗
(
  tool: Tool,
  input: { [key: string]: unknown },
  toolPermissionContext: ToolPermissionContext,
)

Source from the content-addressed store, hash-verified

1028 * Permission result for read permission for the specified tool & tool input
1029 */
1030export function checkReadPermissionForTool(
1031 tool: Tool,
1032 input: { [key: string]: unknown },
1033 toolPermissionContext: ToolPermissionContext,
1034): PermissionDecision {
1035 if (typeof tool.getPath !== 'function') {
1036 return {
1037 behavior: 'ask',
1038 message: `Claude requested permissions to use ${tool.name}, but you haven't granted it yet.`,
1039 }
1040 }
1041 const path = tool.getPath(input)
1042
1043 // Get paths to check (includes both original and resolved symlinks).
1044 // Computed once here and threaded through checkWritePermissionForTool →
1045 // checkPathSafetyForAutoEdit → pathInAllowedWorkingPath to avoid redundant
1046 // existsSync/lstatSync/realpathSync syscalls on the same path (previously
1047 // 6× = 30 syscalls per Read permission check).
1048 const pathsToCheck = getPathsForPermissionCheck(path)
1049
1050 // 1. Defense-in-depth: Block UNC paths early (before other checks)
1051 // This catches paths starting with \\ or // that could access network resources
1052 // This may catch some UNC patterns not detected by containsVulnerableUncPath
1053 for (const pathToCheck of pathsToCheck) {
1054 if (pathToCheck.startsWith('\\\\') || pathToCheck.startsWith('//')) {
1055 return {
1056 behavior: 'ask',
1057 message: `Claude requested permissions to read from ${path}, which appears to be a UNC path that could access network resources.`,
1058 decisionReason: {
1059 type: 'other',
1060 reason: 'UNC path detected (defense-in-depth check)',
1061 },
1062 }
1063 }
1064 }
1065
1066 // 2. Check for suspicious Windows path patterns (defense in depth)
1067 for (const pathToCheck of pathsToCheck) {
1068 if (hasSuspiciousWindowsPathPattern(pathToCheck)) {
1069 return {
1070 behavior: 'ask',
1071 message: `Claude requested permissions to read from ${path}, which contains a suspicious Windows path pattern that requires manual approval.`,
1072 decisionReason: {
1073 type: 'other',
1074 reason:
1075 'Path contains suspicious Windows-specific patterns (alternate data streams, short names, long path prefixes, or three or more consecutive dots) that require manual verification',
1076 },
1077 }
1078 }
1079 }
1080
1081 // 3. Check for READ-SPECIFIC deny rules first - check both the original path and resolved symlink path
1082 // SECURITY: This must come before any allow checks (including "edit access implies read access")
1083 // to prevent bypassing explicit read deny rules
1084 for (const pathToCheck of pathsToCheck) {
1085 const denyRule = matchingRuleForInput(
1086 pathToCheck,
1087 toolPermissionContext,

Callers 4

checkPermissionsFunction · 0.85
checkPermissionsFunction · 0.85
checkPermissionsFunction · 0.85
checkPermissionsFunction · 0.85

Calls 8

matchingRuleForInputFunction · 0.85
pathInAllowedWorkingPathFunction · 0.85
expandPathFunction · 0.85
generateSuggestionsFunction · 0.85

Tested by

no test coverage detected