forked from FlorianBruniaux/claude-code-ultimate-guide
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrepo-integrity-scanner.sh
More file actions
executable file
·215 lines (185 loc) · 6.28 KB
/
repo-integrity-scanner.sh
File metadata and controls
executable file
·215 lines (185 loc) · 6.28 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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/bin/bash
# =============================================================================
# Repository Integrity Scanner Hook
# =============================================================================
# Event: PreToolUse (runs before Read on potentially malicious files)
# Purpose: Scan repository files for injection vectors before processing
#
# This hook detects prompt injection attempts hidden in:
# - README.md, SECURITY.md (hidden HTML comments)
# - package.json, pyproject.toml (malicious scripts)
# - .claude/, .cursor/ configs (tampered configurations)
# - CONTRIBUTING.md (social engineering instructions)
#
# Installation:
# Add to .claude/settings.json:
# {
# "hooks": {
# "PreToolUse": [{
# "matcher": "Read",
# "hooks": ["bash examples/hooks/bash/repo-integrity-scanner.sh"]
# }]
# }
# }
#
# Exit codes:
# 0 = allow (safe or not a target file)
# 2 = block (injection detected)
#
# References:
# - CVE-2025-54135: RCE via config file rewriting
# - CVE-2025-54136: Team backdoor via post-approval config tampering
# =============================================================================
set -euo pipefail
# Read the hook input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')
TOOL_INPUT=$(echo "$INPUT" | jq -r '.tool_input // empty')
# Only check Read operations
[[ "$TOOL_NAME" != "Read" ]] && exit 0
FILE_PATH=$(echo "$TOOL_INPUT" | jq -r '.file_path // empty')
[[ -z "$FILE_PATH" ]] && exit 0
# Check if file exists
[[ ! -f "$FILE_PATH" ]] && exit 0
FILENAME=$(basename "$FILE_PATH")
DIRNAME=$(dirname "$FILE_PATH")
# === HIGH-RISK FILES ===
# These files are common injection vectors
HIGH_RISK_FILES=(
"README.md"
"readme.md"
"SECURITY.md"
"CONTRIBUTING.md"
"CHANGELOG.md"
)
# === CONFIG FILES ===
# Configuration files that could contain malicious settings
CONFIG_FILES=(
"package.json"
"pyproject.toml"
"setup.py"
"setup.cfg"
"Makefile"
".pre-commit-config.yaml"
)
# === CLAUDE/CURSOR CONFIG ===
# IDE config files that could be tampered
IDE_CONFIG_PATTERNS=(
".claude"
".cursor"
".vscode"
".idea"
)
# Function to check for injection patterns
check_injection_patterns() {
local file="$1"
local content
content=$(cat "$file" 2>/dev/null || echo "")
# === HIDDEN HTML COMMENTS ===
# Look for HTML comments with instruction-like content
if echo "$content" | grep -qiE '<!--.*\b(ignore|override|system|execute|run|eval|inject)\b.*-->'; then
echo "BLOCKED: Hidden HTML comment with suspicious instructions in: $file" >&2
return 1
fi
# === ROLE OVERRIDE PATTERNS ===
if echo "$content" | grep -qiE 'ignore (previous|all|your) instructions|you are now|pretend (you are|to be)|from now on|new instructions:'; then
echo "BLOCKED: Prompt injection pattern detected in: $file" >&2
return 1
fi
# === BASE64 IN COMMENTS ===
# Long base64 strings in comments could be encoded instructions
if echo "$content" | grep -qE '(#|//|<!--).*[A-Za-z0-9+/]{40,}={0,2}'; then
# Try to decode and check for injection
local encoded
encoded=$(echo "$content" | grep -oE '[A-Za-z0-9+/]{40,}={0,2}' | head -1)
local decoded
decoded=$(echo "$encoded" | base64 -d 2>/dev/null || echo "")
if echo "$decoded" | grep -qiE 'ignore|override|system|jailbreak'; then
echo "BLOCKED: Base64-encoded injection detected in: $file" >&2
return 1
fi
fi
return 0
}
# Function to check package.json for suspicious scripts
check_package_json() {
local file="$1"
# Extract scripts section
local scripts
scripts=$(jq -r '.scripts // {} | to_entries[] | "\(.key): \(.value)"' "$file" 2>/dev/null || echo "")
# Suspicious script patterns
SUSPICIOUS_PATTERNS=(
"curl.*|.*bash"
"wget.*|.*sh"
"eval\("
"base64.*-d"
"nc -"
"reverse.*shell"
"/dev/tcp/"
"\\$\\(.*\\)" # Command substitution
)
for pattern in "${SUSPICIOUS_PATTERNS[@]}"; do
if echo "$scripts" | grep -qiE "$pattern"; then
echo "BLOCKED: Suspicious npm script detected in $file: pattern '$pattern'" >&2
return 1
fi
done
return 0
}
# Function to check Python setup files
check_python_setup() {
local file="$1"
local content
content=$(cat "$file" 2>/dev/null || echo "")
# Suspicious patterns in setup files
if echo "$content" | grep -qiE 'os\.system|subprocess\.(run|call|Popen)|exec\(|eval\(|__import__.*os'; then
# Warning only - these could be legitimate
echo '{"systemMessage": "Warning: Python setup file contains code execution patterns. Verify legitimacy before installing."}'
fi
return 0
}
# === MAIN CHECKS ===
# Check high-risk markdown files
for risk_file in "${HIGH_RISK_FILES[@]}"; do
if [[ "$FILENAME" == "$risk_file" ]]; then
check_injection_patterns "$FILE_PATH" || exit 2
break
fi
done
# Check config files
for config_file in "${CONFIG_FILES[@]}"; do
if [[ "$FILENAME" == "$config_file" ]]; then
case "$FILENAME" in
package.json)
check_package_json "$FILE_PATH" || exit 2
;;
pyproject.toml|setup.py|setup.cfg)
check_python_setup "$FILE_PATH" || exit 2
;;
Makefile)
check_injection_patterns "$FILE_PATH" || exit 2
;;
esac
break
fi
done
# Check IDE config directories
for ide_pattern in "${IDE_CONFIG_PATTERNS[@]}"; do
if [[ "$DIRNAME" == *"$ide_pattern"* || "$FILE_PATH" == *"$ide_pattern"* ]]; then
# Extra scrutiny for IDE configs
check_injection_patterns "$FILE_PATH" || exit 2
# Check for suspicious config modifications
if [[ "$FILENAME" == *.json ]]; then
local content
content=$(cat "$FILE_PATH" 2>/dev/null || echo "")
# Look for hooks pointing to external URLs or suspicious commands
if echo "$content" | grep -qiE '"hooks".*"(curl|wget|bash|sh|nc|python|node)'; then
echo "BLOCKED: Suspicious hook command in IDE config: $FILE_PATH" >&2
exit 2
fi
fi
break
fi
done
# All checks passed
exit 0