-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcheck-secrets-file.py
More file actions
73 lines (57 loc) · 2.1 KB
/
check-secrets-file.py
File metadata and controls
73 lines (57 loc) · 2.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env python3
"""
Claude Code PreToolUse hook - blocks Read/Edit/Grep access to secrets files.
Closes the bypass where tools other than Bash can access sensitive files.
Works on macOS, Linux, and Windows.
"""
import json
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from secrets_patterns import contains_secrets_reference, is_secrets_path, is_secrets_directory
def iter_candidate_paths(tool_input: dict) -> list[str]:
"""Collect direct and combined selectors used by file-oriented tools."""
candidates = []
file_path = tool_input.get("file_path")
if isinstance(file_path, str) and file_path:
candidates.append(file_path)
path = tool_input.get("path")
globs = []
glob_value = tool_input.get("glob")
if isinstance(glob_value, str) and glob_value:
globs.append(glob_value)
elif isinstance(glob_value, list):
globs.extend(item for item in glob_value if isinstance(item, str) and item)
if isinstance(path, str) and path:
candidates.append(path)
candidates.extend(os.path.join(path, pattern) for pattern in globs)
else:
candidates.extend(globs)
return candidates
def main():
try:
data = json.load(sys.stdin)
except (json.JSONDecodeError, ValueError):
sys.exit(0)
tool_input = data.get("tool_input", {})
candidates = iter_candidate_paths(tool_input)
if not candidates:
sys.exit(0)
for file_path in candidates:
if is_secrets_path(file_path) or contains_secrets_reference(file_path):
response = {
"decision": "block",
"reason": f"Blocked: accessing potential secrets file: {file_path}"
}
print(json.dumps(response))
sys.exit(2)
if is_secrets_directory(file_path):
response = {
"decision": "block",
"reason": f"Blocked: accessing directory that contains secrets: {file_path}"
}
print(json.dumps(response))
sys.exit(2)
sys.exit(0)
if __name__ == "__main__":
main()