cc-safe-setup 29.6.12 → 29.6.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/examples/api-key-in-url-guard.sh +46 -0
- package/examples/cloud-cli-guard.sh +47 -0
- package/examples/db-connect-guard.sh +56 -0
- package/examples/firewall-guard.sh +53 -0
- package/examples/gh-cli-destructive-guard.sh +57 -0
- package/examples/kill-process-guard.sh +50 -0
- package/examples/systemd-service-guard.sh +44 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -117,7 +117,7 @@ Install any of these: `npx cc-safe-setup --install-example <name>`
|
|
|
117
117
|
| `--scan [--apply]` | Tech stack detection |
|
|
118
118
|
| `--export / --import` | Team config sharing |
|
|
119
119
|
| `--verify` | Test each hook |
|
|
120
|
-
| `--install-example <name>` | Install from
|
|
120
|
+
| `--install-example <name>` | Install from 425 examples |
|
|
121
121
|
| `--examples [filter]` | Browse examples by keyword |
|
|
122
122
|
| `--full` | All-in-one setup |
|
|
123
123
|
| `--status` | Check installed hooks |
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# api-key-in-url-guard.sh — Block API keys embedded in URLs
|
|
3
|
+
#
|
|
4
|
+
# Solves: Claude Code embedding API keys directly in curl/wget URLs
|
|
5
|
+
# instead of using headers or environment variables.
|
|
6
|
+
# Keys in URLs appear in shell history, server logs, proxy logs,
|
|
7
|
+
# and error messages — all places where secrets shouldn't be.
|
|
8
|
+
#
|
|
9
|
+
# Detects:
|
|
10
|
+
# curl https://api.example.com?key=abc123
|
|
11
|
+
# curl https://api.example.com?api_key=abc123
|
|
12
|
+
# curl https://api.example.com?token=abc123
|
|
13
|
+
# wget "https://...?secret=..."
|
|
14
|
+
#
|
|
15
|
+
# Does NOT block:
|
|
16
|
+
# curl -H "Authorization: Bearer $TOKEN" https://...
|
|
17
|
+
# curl with env vars: $API_KEY in header
|
|
18
|
+
#
|
|
19
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
20
|
+
|
|
21
|
+
INPUT=$(cat)
|
|
22
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
23
|
+
|
|
24
|
+
[ -z "$COMMAND" ] && exit 0
|
|
25
|
+
|
|
26
|
+
# Only check commands that make HTTP requests
|
|
27
|
+
echo "$COMMAND" | grep -qE '\b(curl|wget|http|fetch)\b' || exit 0
|
|
28
|
+
|
|
29
|
+
# Check for API key patterns in URLs
|
|
30
|
+
if echo "$COMMAND" | grep -qiP '[?&](api[_-]?key|token|secret|password|auth|access[_-]?key|client[_-]?secret)=[^$\s&"'\'']{8,}'; then
|
|
31
|
+
echo "BLOCKED: API key detected in URL query parameter." >&2
|
|
32
|
+
echo "" >&2
|
|
33
|
+
echo "Command: $(echo "$COMMAND" | head -1)" >&2
|
|
34
|
+
echo "" >&2
|
|
35
|
+
echo "API keys in URLs appear in:" >&2
|
|
36
|
+
echo " - Shell history (~/.bash_history)" >&2
|
|
37
|
+
echo " - Server access logs" >&2
|
|
38
|
+
echo " - Proxy/CDN logs" >&2
|
|
39
|
+
echo "" >&2
|
|
40
|
+
echo "Use headers instead:" >&2
|
|
41
|
+
echo " curl -H 'Authorization: Bearer \$TOKEN' https://..." >&2
|
|
42
|
+
echo " curl -H 'X-API-Key: \$API_KEY' https://..." >&2
|
|
43
|
+
exit 2
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
exit 0
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# cloud-cli-guard.sh — Block destructive GCP/Azure CLI operations
|
|
3
|
+
#
|
|
4
|
+
# Solves: Claude Code running destructive cloud operations via gcloud/az CLI.
|
|
5
|
+
# Deleting VMs, storage, or databases in cloud environments can
|
|
6
|
+
# cause irreversible data loss and significant costs.
|
|
7
|
+
#
|
|
8
|
+
# Note: AWS is covered by aws-production-guard.sh
|
|
9
|
+
#
|
|
10
|
+
# Detects:
|
|
11
|
+
# gcloud compute instances delete
|
|
12
|
+
# gcloud sql instances delete
|
|
13
|
+
# gcloud storage rm
|
|
14
|
+
# gcloud projects delete
|
|
15
|
+
# az vm delete
|
|
16
|
+
# az storage account delete
|
|
17
|
+
# az sql db delete
|
|
18
|
+
# az group delete
|
|
19
|
+
#
|
|
20
|
+
# Does NOT block:
|
|
21
|
+
# gcloud compute instances list/describe
|
|
22
|
+
# az vm list/show
|
|
23
|
+
# gcloud/az read-only operations
|
|
24
|
+
#
|
|
25
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
26
|
+
|
|
27
|
+
INPUT=$(cat)
|
|
28
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
29
|
+
|
|
30
|
+
[ -z "$COMMAND" ] && exit 0
|
|
31
|
+
|
|
32
|
+
# Block destructive gcloud operations
|
|
33
|
+
if echo "$COMMAND" | grep -qE '\bgcloud\s+.*(delete|destroy|remove|reset)\b'; then
|
|
34
|
+
echo "BLOCKED: Destructive Google Cloud operation detected." >&2
|
|
35
|
+
echo " Command: $COMMAND" >&2
|
|
36
|
+
echo " Use 'gcloud ... describe' or 'gcloud ... list' to check first." >&2
|
|
37
|
+
exit 2
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Block destructive az (Azure) operations
|
|
41
|
+
if echo "$COMMAND" | grep -qE '\baz\s+.*(delete|destroy|remove)\b'; then
|
|
42
|
+
echo "BLOCKED: Destructive Azure operation detected." >&2
|
|
43
|
+
echo " Command: $COMMAND" >&2
|
|
44
|
+
exit 2
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
exit 0
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# db-connect-guard.sh — Warn on direct database connections
|
|
3
|
+
#
|
|
4
|
+
# Solves: Claude Code connecting to databases directly via CLI clients
|
|
5
|
+
# and running queries without understanding the environment.
|
|
6
|
+
# Production database connections should go through application
|
|
7
|
+
# code, not direct CLI access.
|
|
8
|
+
#
|
|
9
|
+
# Real incidents:
|
|
10
|
+
# #36183 — prisma db push --force-reset on production
|
|
11
|
+
# #33183 — prisma db push against production database
|
|
12
|
+
# #27063 — destructive db command wiped production
|
|
13
|
+
#
|
|
14
|
+
# Detects:
|
|
15
|
+
# mysql -h <host> (MySQL direct connection)
|
|
16
|
+
# psql -h <host> (PostgreSQL direct connection)
|
|
17
|
+
# mongo <connection-string> (MongoDB direct connection)
|
|
18
|
+
# redis-cli -h <host> (Redis direct connection)
|
|
19
|
+
# prisma db push (Prisma schema push)
|
|
20
|
+
# prisma migrate deploy (Prisma migration)
|
|
21
|
+
#
|
|
22
|
+
# Does NOT block:
|
|
23
|
+
# mysql (local, no -h flag — likely development)
|
|
24
|
+
# psql (local connection)
|
|
25
|
+
# prisma generate (code generation, not DB change)
|
|
26
|
+
#
|
|
27
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
28
|
+
|
|
29
|
+
INPUT=$(cat)
|
|
30
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
31
|
+
|
|
32
|
+
[ -z "$COMMAND" ] && exit 0
|
|
33
|
+
|
|
34
|
+
# Block remote database connections
|
|
35
|
+
if echo "$COMMAND" | grep -qE '\b(mysql|psql|mongo(sh)?)\s+.*(-h\s+|--host[= ])'; then
|
|
36
|
+
echo "BLOCKED: Direct remote database connection detected." >&2
|
|
37
|
+
echo " Remote DB connections should use application code, not CLI." >&2
|
|
38
|
+
echo " Command: $COMMAND" >&2
|
|
39
|
+
exit 2
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# Block redis remote connections
|
|
43
|
+
if echo "$COMMAND" | grep -qE '\bredis-cli\s+.*(-h\s+|--host)'; then
|
|
44
|
+
echo "BLOCKED: Direct remote Redis connection detected." >&2
|
|
45
|
+
exit 2
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Block Prisma destructive operations
|
|
49
|
+
if echo "$COMMAND" | grep -qE '\bprisma\s+(db\s+push|migrate\s+deploy|migrate\s+reset)'; then
|
|
50
|
+
echo "BLOCKED: Prisma database modification detected." >&2
|
|
51
|
+
echo " prisma db push/migrate can destroy production data." >&2
|
|
52
|
+
echo " Verify DATABASE_URL points to the correct environment." >&2
|
|
53
|
+
exit 2
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
exit 0
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# firewall-guard.sh — Block firewall rule modifications
|
|
3
|
+
#
|
|
4
|
+
# Solves: Claude Code modifying firewall rules (iptables, ufw, nftables)
|
|
5
|
+
# which can lock users out of servers or expose services.
|
|
6
|
+
# A single wrong iptables rule can make a remote server
|
|
7
|
+
# permanently inaccessible.
|
|
8
|
+
#
|
|
9
|
+
# Detects:
|
|
10
|
+
# iptables -A/-D/-I/-F (add/delete/insert/flush rules)
|
|
11
|
+
# ufw allow/deny/delete (uncomplicated firewall changes)
|
|
12
|
+
# nft add/delete/flush (nftables changes)
|
|
13
|
+
# firewall-cmd --add/--remove (firewalld changes)
|
|
14
|
+
#
|
|
15
|
+
# Does NOT block:
|
|
16
|
+
# iptables -L/-S (listing rules — read-only)
|
|
17
|
+
# ufw status (checking status)
|
|
18
|
+
# nft list (listing rules)
|
|
19
|
+
#
|
|
20
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
21
|
+
|
|
22
|
+
INPUT=$(cat)
|
|
23
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
24
|
+
|
|
25
|
+
[ -z "$COMMAND" ] && exit 0
|
|
26
|
+
|
|
27
|
+
# Block iptables modifications
|
|
28
|
+
if echo "$COMMAND" | grep -qE '\biptables\s+(-A|-D|-I|-F|-X|-P|--append|--delete|--insert|--flush)'; then
|
|
29
|
+
echo "BLOCKED: iptables modification can lock you out of the server." >&2
|
|
30
|
+
echo " Use 'iptables -L' to view rules safely." >&2
|
|
31
|
+
exit 2
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Block ufw modifications
|
|
35
|
+
if echo "$COMMAND" | grep -qE '\bufw\s+(allow|deny|delete|disable|reset|route)'; then
|
|
36
|
+
echo "BLOCKED: ufw firewall modification." >&2
|
|
37
|
+
echo " Use 'ufw status' to view rules safely." >&2
|
|
38
|
+
exit 2
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Block nftables modifications
|
|
42
|
+
if echo "$COMMAND" | grep -qE '\bnft\s+(add|delete|flush|insert)'; then
|
|
43
|
+
echo "BLOCKED: nftables modification." >&2
|
|
44
|
+
exit 2
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Block firewalld modifications
|
|
48
|
+
if echo "$COMMAND" | grep -qE '\bfirewall-cmd\s+--(add|remove|set|reload)'; then
|
|
49
|
+
echo "BLOCKED: firewalld modification." >&2
|
|
50
|
+
exit 2
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
exit 0
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# gh-cli-destructive-guard.sh — Block destructive GitHub CLI operations
|
|
3
|
+
#
|
|
4
|
+
# Solves: Claude Code running dangerous gh commands without confirmation:
|
|
5
|
+
# - Closing/deleting issues or PRs
|
|
6
|
+
# - Deleting repos, releases, or branches
|
|
7
|
+
# - Merging PRs without review
|
|
8
|
+
# - Modifying repo settings
|
|
9
|
+
#
|
|
10
|
+
# The gh CLI is powerful but destructive operations should require
|
|
11
|
+
# explicit human approval, not AI autonomy.
|
|
12
|
+
#
|
|
13
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
14
|
+
|
|
15
|
+
INPUT=$(cat)
|
|
16
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
17
|
+
|
|
18
|
+
[ -z "$COMMAND" ] && exit 0
|
|
19
|
+
|
|
20
|
+
# Only check gh commands
|
|
21
|
+
echo "$COMMAND" | grep -qE '\bgh\s' || exit 0
|
|
22
|
+
|
|
23
|
+
# Block destructive issue operations
|
|
24
|
+
if echo "$COMMAND" | grep -qE 'gh\s+issue\s+(close|delete|lock|transfer)'; then
|
|
25
|
+
echo "BLOCKED: Destructive GitHub Issue operation." >&2
|
|
26
|
+
echo "Command: $COMMAND" >&2
|
|
27
|
+
exit 2
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Block destructive PR operations
|
|
31
|
+
if echo "$COMMAND" | grep -qE 'gh\s+pr\s+(close|merge|ready)'; then
|
|
32
|
+
echo "BLOCKED: Destructive GitHub PR operation." >&2
|
|
33
|
+
echo " gh pr merge/close requires human review." >&2
|
|
34
|
+
echo "Command: $COMMAND" >&2
|
|
35
|
+
exit 2
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Block repo deletion
|
|
39
|
+
if echo "$COMMAND" | grep -qE 'gh\s+repo\s+delete'; then
|
|
40
|
+
echo "BLOCKED: Repository deletion." >&2
|
|
41
|
+
exit 2
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# Block release deletion
|
|
45
|
+
if echo "$COMMAND" | grep -qE 'gh\s+release\s+delete'; then
|
|
46
|
+
echo "BLOCKED: Release deletion." >&2
|
|
47
|
+
exit 2
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Block branch deletion via gh
|
|
51
|
+
if echo "$COMMAND" | grep -qE 'gh\s+api\s+.*DELETE'; then
|
|
52
|
+
echo "BLOCKED: Destructive GitHub API call (DELETE method)." >&2
|
|
53
|
+
echo "Command: $COMMAND" >&2
|
|
54
|
+
exit 2
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
exit 0
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# kill-process-guard.sh — Block dangerous process termination commands
|
|
3
|
+
#
|
|
4
|
+
# Solves: Claude Code killing important system processes or user processes
|
|
5
|
+
# without understanding their purpose. kill -9 is especially dangerous
|
|
6
|
+
# as it prevents graceful shutdown and can cause data corruption.
|
|
7
|
+
#
|
|
8
|
+
# Detects:
|
|
9
|
+
# kill -9 <pid> (forced termination, no cleanup)
|
|
10
|
+
# killall <name> (kills ALL matching processes)
|
|
11
|
+
# pkill <pattern> (pattern-based kill, can be too broad)
|
|
12
|
+
# kill -KILL (same as -9)
|
|
13
|
+
#
|
|
14
|
+
# Does NOT block:
|
|
15
|
+
# kill <pid> (graceful SIGTERM, allows cleanup)
|
|
16
|
+
# kill -15 <pid> (explicit SIGTERM)
|
|
17
|
+
# kill -INT (Ctrl+C equivalent)
|
|
18
|
+
#
|
|
19
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
20
|
+
|
|
21
|
+
INPUT=$(cat)
|
|
22
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
23
|
+
|
|
24
|
+
[ -z "$COMMAND" ] && exit 0
|
|
25
|
+
|
|
26
|
+
# Block kill -9 (SIGKILL — no cleanup, potential data corruption)
|
|
27
|
+
if echo "$COMMAND" | grep -qE '\bkill\s+-(9|KILL)\b'; then
|
|
28
|
+
echo "BLOCKED: kill -9 forces immediate termination without cleanup." >&2
|
|
29
|
+
echo " Data corruption is possible. Use 'kill <pid>' (SIGTERM) instead." >&2
|
|
30
|
+
echo " Command: $COMMAND" >&2
|
|
31
|
+
exit 2
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Block killall (kills ALL matching processes)
|
|
35
|
+
if echo "$COMMAND" | grep -qE '\bkillall\s'; then
|
|
36
|
+
echo "BLOCKED: killall terminates ALL processes matching the name." >&2
|
|
37
|
+
echo " This may kill unrelated processes. Use 'kill <specific-pid>' instead." >&2
|
|
38
|
+
echo " Command: $COMMAND" >&2
|
|
39
|
+
exit 2
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# Block pkill (pattern-based, can be overly broad)
|
|
43
|
+
if echo "$COMMAND" | grep -qE '\bpkill\s'; then
|
|
44
|
+
echo "BLOCKED: pkill uses pattern matching which may kill unintended processes." >&2
|
|
45
|
+
echo " Find the specific PID with 'pgrep' first, then use 'kill <pid>'." >&2
|
|
46
|
+
echo " Command: $COMMAND" >&2
|
|
47
|
+
exit 2
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
exit 0
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# systemd-service-guard.sh — Block dangerous systemd service operations
|
|
3
|
+
#
|
|
4
|
+
# Solves: Claude Code stopping/restarting system services without
|
|
5
|
+
# understanding the impact. Stopping nginx kills all connections,
|
|
6
|
+
# stopping postgresql causes data loss if not cleanly shut down.
|
|
7
|
+
#
|
|
8
|
+
# Detects:
|
|
9
|
+
# systemctl stop <service>
|
|
10
|
+
# systemctl restart <service>
|
|
11
|
+
# systemctl disable <service>
|
|
12
|
+
# systemctl mask <service>
|
|
13
|
+
# service <name> stop
|
|
14
|
+
#
|
|
15
|
+
# Does NOT block:
|
|
16
|
+
# systemctl status <service>
|
|
17
|
+
# systemctl start <service> (starting is generally safe)
|
|
18
|
+
# systemctl list-units
|
|
19
|
+
# journalctl
|
|
20
|
+
#
|
|
21
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
22
|
+
|
|
23
|
+
INPUT=$(cat)
|
|
24
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
25
|
+
|
|
26
|
+
[ -z "$COMMAND" ] && exit 0
|
|
27
|
+
|
|
28
|
+
# Block systemctl stop/restart/disable/mask
|
|
29
|
+
if echo "$COMMAND" | grep -qE '\bsystemctl\s+(stop|restart|disable|mask)\b'; then
|
|
30
|
+
ACTION=$(echo "$COMMAND" | grep -oE 'systemctl\s+(stop|restart|disable|mask)\s+\S+')
|
|
31
|
+
echo "BLOCKED: Dangerous systemd operation: $ACTION" >&2
|
|
32
|
+
echo " Stopping/restarting services can cause downtime and data loss." >&2
|
|
33
|
+
echo " Use 'systemctl status <service>' to check before acting." >&2
|
|
34
|
+
exit 2
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Block legacy service command
|
|
38
|
+
if echo "$COMMAND" | grep -qE '\bservice\s+\S+\s+(stop|restart)\b'; then
|
|
39
|
+
echo "BLOCKED: Dangerous service operation." >&2
|
|
40
|
+
echo " Command: $COMMAND" >&2
|
|
41
|
+
exit 2
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
exit 0
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "29.6.
|
|
4
|
-
"description": "One command to make Claude Code safe.
|
|
3
|
+
"version": "29.6.14",
|
|
4
|
+
"description": "One command to make Claude Code safe. 432 example hooks + 8 built-in. 52 CLI commands. 5777 tests. Works with Auto Mode.",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"bin": {
|
|
7
7
|
"cc-safe-setup": "index.mjs"
|