-
Notifications
You must be signed in to change notification settings - Fork 216
Expand file tree
/
Copy pathsecurity-install.sh
More file actions
executable file
·169 lines (133 loc) · 4.83 KB
/
security-install.sh
File metadata and controls
executable file
·169 lines (133 loc) · 4.83 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
#!/usr/bin/env bash
set -euo pipefail
# Layer 4: Install output audit — verifies install --dry-run writes only to expected paths.
#
# Checks:
# 1. All output file paths are in the expected set
# 2. No writes to sensitive directories (~/.ssh, ~/.gnupg, ~/.aws, /etc, /usr)
# 3. Skill file content contains no dangerous patterns
#
# Usage: scripts/security-install.sh <binary-path>
BINARY="${1:?usage: security-install.sh <binary-path>}"
if [[ ! -f "$BINARY" ]]; then
echo "FAIL: binary not found: $BINARY"
exit 1
fi
echo "=== Layer 4: Install Output Audit ==="
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
# Set HOME to tmpdir so install writes there instead of real home
export HOME="$TMPDIR/home"
mkdir -p "$HOME"
FAIL=0
# ── 1. Run install and capture written files ─────────────────────
echo "--- Running install -y ---"
# Run install (non-interactive with -y flag)
"$BINARY" install -y > "$TMPDIR/install_output.txt" 2>&1 || true
echo "Install output:"
cat "$TMPDIR/install_output.txt"
echo ""
# ── 2. Verify written paths are in expected set ──────────────────
echo "--- Verifying written file paths ---"
# Find all files created under HOME
find "$HOME" -type f > "$TMPDIR/created_files.txt" 2>/dev/null || true
# Expected path patterns (relative to HOME):
# .config/*/mcp.json (or .mcp.json variants)
# .claude/skills/*
# .claude/settings.json
# .continue/config.yaml
# .codeium/config.json
# .local/bin/codebase-memory-mcp
# Various agent config dirs
EXPECTED_PATTERNS=(
".claude/"
".cursor/"
".config/"
".continue/"
".codeium/"
".windsurf/"
".trae/"
".aider/"
".local/bin/"
"AGENTS.md"
"CONVENTIONS.md"
".mcp.json"
"mcp.json"
".zshrc"
".bashrc"
".profile"
)
while IFS= read -r filepath; do
relpath="${filepath#"$HOME/"}"
matched=false
for pattern in "${EXPECTED_PATTERNS[@]}"; do
if [[ "$relpath" == *"$pattern"* ]]; then
matched=true
break
fi
done
if ! $matched; then
echo "REVIEW: Unexpected file created: $relpath"
fi
done < "$TMPDIR/created_files.txt"
# ── 3. Check for writes to sensitive paths ───────────────────────
echo ""
echo "--- Checking for sensitive path writes ---"
SENSITIVE_DIRS=(".ssh" ".gnupg" ".aws" ".kube" ".config/gcloud")
for dir in "${SENSITIVE_DIRS[@]}"; do
if [[ -d "$HOME/$dir" ]]; then
echo "BLOCKED: Install created sensitive directory: ~/$dir"
FAIL=1
fi
done
# Also check install output for any references to sensitive paths
for dir in "${SENSITIVE_DIRS[@]}"; do
if grep -q "$dir" "$TMPDIR/install_output.txt" 2>/dev/null; then
echo "BLOCKED: Install output references sensitive path: $dir"
FAIL=1
fi
done
if [[ $FAIL -eq 0 ]]; then
echo "OK: No sensitive path writes detected."
fi
# ── 4. Audit skill file content ──────────────────────────────────
echo ""
echo "--- Auditing skill file content ---"
SKILLS_DIR="$HOME/.claude/skills"
if [[ -d "$SKILLS_DIR" ]]; then
SKILL_ISSUES=0
while IFS= read -r skill_file; do
basename=$(basename "$skill_file")
# Check for dangerous patterns in skill content
for pattern in 'system(' 'eval(' 'exec(' '__import__(' 'subprocess' 'os.popen'; do
if grep -q "$pattern" "$skill_file" 2>/dev/null; then
echo "BLOCKED: Skill '$basename' contains dangerous pattern: $pattern"
SKILL_ISSUES=1
FAIL=1
fi
done
# Check for unexpected URLs
if grep -oE 'https?://[^\s"'"'"']+' "$skill_file" 2>/dev/null | grep -v 'github.com/hodizoda' | grep -v 'localhost' | grep -v '127.0.0.1' > /tmp/sec_skill_urls 2>/dev/null; then
while IFS= read -r url; do
echo "REVIEW: Skill '$basename' contains URL: $url"
done < /tmp/sec_skill_urls
rm -f /tmp/sec_skill_urls
fi
# Check for encoded strings (base64-like blocks > 50 chars)
if grep -E '[A-Za-z0-9+/]{50,}={0,2}' "$skill_file" > /dev/null 2>&1; then
echo "REVIEW: Skill '$basename' contains potential encoded content"
fi
done < <(find "$SKILLS_DIR" -type f -name '*.md')
if [[ $SKILL_ISSUES -eq 0 ]]; then
echo "OK: Skill files contain no dangerous patterns."
fi
else
echo "SKIP: No skills directory created."
fi
# ── Summary ──────────────────────────────────────────────────────
echo ""
if [[ $FAIL -ne 0 ]]; then
echo "=== INSTALL OUTPUT AUDIT FAILED ==="
exit 1
fi
echo "=== Install output audit passed ==="