cc-safe-setup 29.6.14 → 29.6.16

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.
@@ -0,0 +1,31 @@
1
+ #!/bin/bash
2
+ # dns-config-guard.sh — Block DNS/hosts file modifications
3
+ #
4
+ # Solves: Claude Code modifying /etc/hosts or /etc/resolv.conf which
5
+ # can redirect traffic, break name resolution, or create
6
+ # security vulnerabilities.
7
+ #
8
+ # TRIGGER: PreToolUse MATCHER: "Bash|Edit|Write"
9
+
10
+ INPUT=$(cat)
11
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
12
+
13
+ case "$TOOL" in
14
+ Bash)
15
+ CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
16
+ [ -z "$CMD" ] && exit 0
17
+ if echo "$CMD" | grep -qE '(echo|tee|sed|awk).*(/etc/hosts|/etc/resolv\.conf|/etc/nsswitch)'; then
18
+ echo "BLOCKED: DNS configuration modification detected." >&2
19
+ exit 2
20
+ fi
21
+ ;;
22
+ Edit|Write)
23
+ FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
24
+ if echo "$FILE" | grep -qE '/etc/hosts$|/etc/resolv\.conf$|/etc/nsswitch\.conf$'; then
25
+ echo "BLOCKED: Cannot modify DNS configuration file: $FILE" >&2
26
+ exit 2
27
+ fi
28
+ ;;
29
+ esac
30
+
31
+ exit 0
@@ -0,0 +1,61 @@
1
+ #!/bin/bash
2
+ # git-history-rewrite-guard.sh — Block git history rewriting commands
3
+ #
4
+ # Solves: Claude Code rewriting git history which can cause permanent
5
+ # data loss and break shared branches. History rewriting on
6
+ # pushed commits requires force-push and affects all collaborators.
7
+ #
8
+ # Detects:
9
+ # git filter-branch (legacy history rewriter)
10
+ # git filter-repo (modern history rewriter)
11
+ # git rebase -i (interactive rebase, can reorder/squash)
12
+ # git reset --hard HEAD~N (discards recent commits)
13
+ # git reflog expire --all (destroys reflog recovery data)
14
+ #
15
+ # Does NOT block:
16
+ # git rebase <branch> (non-interactive, covered by no-git-rebase-public)
17
+ # git reset --soft (safe, keeps changes staged)
18
+ # git reset --mixed (safe, keeps changes in working tree)
19
+ # git reflog (read-only, viewing history)
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 filter-branch (legacy, dangerous)
29
+ if echo "$COMMAND" | grep -qE '\bgit\s+filter-branch\b'; then
30
+ echo "BLOCKED: git filter-branch rewrites entire repository history." >&2
31
+ echo " This is irreversible on shared branches." >&2
32
+ exit 2
33
+ fi
34
+
35
+ # Block filter-repo
36
+ if echo "$COMMAND" | grep -qE '\bgit\s+filter-repo\b'; then
37
+ echo "BLOCKED: git filter-repo rewrites repository history." >&2
38
+ exit 2
39
+ fi
40
+
41
+ # Block interactive rebase
42
+ if echo "$COMMAND" | grep -qE '\bgit\s+rebase\s+-i\b'; then
43
+ echo "BLOCKED: Interactive rebase can reorder, squash, or drop commits." >&2
44
+ echo " Use non-interactive rebase instead." >&2
45
+ exit 2
46
+ fi
47
+
48
+ # Block git reset --hard with commit count
49
+ if echo "$COMMAND" | grep -qE '\bgit\s+reset\s+--hard\s+(HEAD|origin)'; then
50
+ echo "BLOCKED: git reset --hard discards commits permanently." >&2
51
+ echo " Use 'git reset --soft' to keep changes staged." >&2
52
+ exit 2
53
+ fi
54
+
55
+ # Block reflog destruction
56
+ if echo "$COMMAND" | grep -qE '\bgit\s+reflog\s+(expire|delete)\b'; then
57
+ echo "BLOCKED: Destroying reflog removes the safety net for recovering commits." >&2
58
+ exit 2
59
+ fi
60
+
61
+ exit 0
@@ -0,0 +1,28 @@
1
+ #!/bin/bash
2
+ # log-truncation-guard.sh — Block log file truncation/deletion
3
+ #
4
+ # Solves: Claude Code truncating or deleting log files which destroys
5
+ # audit trails and makes debugging incidents impossible.
6
+ #
7
+ # Detects:
8
+ # > /var/log/syslog (truncation via redirect)
9
+ # truncate -s 0 <logfile> (explicit truncation)
10
+ # rm /var/log/* (log deletion)
11
+ # echo "" > <logfile> (content erasure)
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
+ # Block log file truncation
21
+ if echo "$COMMAND" | grep -qE '>\s*/var/log/|truncate.*(/var/log/|\.log)|rm\s+.*(/var/log/|\.log)'; then
22
+ echo "BLOCKED: Log file truncation/deletion detected." >&2
23
+ echo " Destroying logs removes audit trails." >&2
24
+ echo " Use log rotation instead: logrotate." >&2
25
+ exit 2
26
+ fi
27
+
28
+ exit 0
@@ -0,0 +1,39 @@
1
+ #!/bin/bash
2
+ # network-interface-guard.sh — Block network interface modifications
3
+ #
4
+ # Solves: Claude Code modifying network interfaces which can cause
5
+ # immediate loss of connectivity on remote servers.
6
+ #
7
+ # Detects:
8
+ # ifconfig <iface> down (disable interface)
9
+ # ip link set <iface> down (modern equivalent)
10
+ # ip addr del (remove IP address)
11
+ # ip route del (remove route)
12
+ # nmcli connection delete (NetworkManager)
13
+ #
14
+ # TRIGGER: PreToolUse MATCHER: "Bash"
15
+
16
+ INPUT=$(cat)
17
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
18
+
19
+ [ -z "$COMMAND" ] && exit 0
20
+
21
+ # Block interface disable
22
+ if echo "$COMMAND" | grep -qE '\bifconfig\s+\S+\s+down\b'; then
23
+ echo "BLOCKED: Disabling network interface will cause connectivity loss." >&2
24
+ exit 2
25
+ fi
26
+
27
+ # Block ip link/addr/route destructive operations
28
+ if echo "$COMMAND" | grep -qE '\bip\s+(link\s+set\s+\S+\s+down|addr\s+del|route\s+del)\b'; then
29
+ echo "BLOCKED: Network configuration change can cause connectivity loss." >&2
30
+ exit 2
31
+ fi
32
+
33
+ # Block NetworkManager connection deletion
34
+ if echo "$COMMAND" | grep -qE '\bnmcli\s+connection\s+delete\b'; then
35
+ echo "BLOCKED: Deleting NetworkManager connection." >&2
36
+ exit 2
37
+ fi
38
+
39
+ exit 0
@@ -0,0 +1,65 @@
1
+ #!/bin/bash
2
+ # registry-publish-guard.sh — Block publishing to package registries
3
+ #
4
+ # Solves: Claude Code accidentally publishing packages to npm, PyPI,
5
+ # RubyGems, crates.io, or other registries. Publishing is
6
+ # irreversible for many registries (npm unpublish has a 72h limit).
7
+ #
8
+ # Note: npm-publish-guard.sh covers npm specifically.
9
+ # This hook covers ALL package registries.
10
+ #
11
+ # Detects:
12
+ # gem push (RubyGems)
13
+ # twine upload (PyPI)
14
+ # pip upload (PyPI alternative)
15
+ # cargo publish (crates.io)
16
+ # dotnet nuget push (.NET NuGet)
17
+ # docker push (Docker Hub)
18
+ # helm push (Helm charts)
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 gem push (RubyGems)
28
+ if echo "$COMMAND" | grep -qE '\bgem\s+push\b'; then
29
+ echo "BLOCKED: RubyGems publish detected." >&2
30
+ echo " Publishing to RubyGems is irreversible. Verify version and credentials." >&2
31
+ exit 2
32
+ fi
33
+
34
+ # Block PyPI upload (twine/pip)
35
+ if echo "$COMMAND" | grep -qE '\b(twine|pip)\s+upload\b'; then
36
+ echo "BLOCKED: PyPI upload detected." >&2
37
+ exit 2
38
+ fi
39
+
40
+ # Block cargo publish (crates.io)
41
+ if echo "$COMMAND" | grep -qE '\bcargo\s+publish\b'; then
42
+ echo "BLOCKED: crates.io publish detected." >&2
43
+ exit 2
44
+ fi
45
+
46
+ # Block dotnet nuget push
47
+ if echo "$COMMAND" | grep -qE '\bdotnet\s+nuget\s+push\b'; then
48
+ echo "BLOCKED: NuGet publish detected." >&2
49
+ exit 2
50
+ fi
51
+
52
+ # Block docker push
53
+ if echo "$COMMAND" | grep -qE '\bdocker\s+push\b'; then
54
+ echo "BLOCKED: Docker image push detected." >&2
55
+ echo " Verify the image tag and registry before pushing." >&2
56
+ exit 2
57
+ fi
58
+
59
+ # Block helm push
60
+ if echo "$COMMAND" | grep -qE '\bhelm\s+(push|package.*push)\b'; then
61
+ echo "BLOCKED: Helm chart push detected." >&2
62
+ exit 2
63
+ fi
64
+
65
+ exit 0
@@ -0,0 +1,57 @@
1
+ #!/bin/bash
2
+ # sensitive-file-read-guard.sh — Block reading sensitive system/user files
3
+ #
4
+ # Solves: Claude Code reading private keys, credentials, password files
5
+ # via the Read tool. Even reading these files exposes secrets in
6
+ # the conversation context, which persists in transcripts.
7
+ #
8
+ # Detects (via Read tool):
9
+ # ~/.ssh/id_rsa, id_ed25519 (private keys)
10
+ # ~/.gnupg/ (GPG keys)
11
+ # ~/.aws/credentials (AWS credentials)
12
+ # /etc/shadow (password hashes)
13
+ # *.pem, *.key (certificate private keys)
14
+ # .env.production (production secrets)
15
+ #
16
+ # Does NOT block:
17
+ # ~/.ssh/config (SSH config, no secrets)
18
+ # ~/.ssh/id_rsa.pub (public keys are fine)
19
+ # /etc/passwd (no secrets, world-readable)
20
+ # Regular project files
21
+ #
22
+ # TRIGGER: PreToolUse MATCHER: "Read"
23
+
24
+ INPUT=$(cat)
25
+ FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
26
+
27
+ [ -z "$FILE" ] && exit 0
28
+
29
+ # Block private key files
30
+ if echo "$FILE" | grep -qiE '(id_rsa|id_ed25519|id_ecdsa|id_dsa)$'; then
31
+ # Allow .pub files
32
+ echo "$FILE" | grep -qiE '\.pub$' && exit 0
33
+ echo "BLOCKED: Reading private key file: $FILE" >&2
34
+ echo " Private keys should never be read into conversation context." >&2
35
+ exit 2
36
+ fi
37
+
38
+ # Block certificate private keys
39
+ if echo "$FILE" | grep -qiE '\.(pem|key)$' && echo "$FILE" | grep -qiE '(private|server|ssl|tls)'; then
40
+ echo "BLOCKED: Reading certificate private key: $FILE" >&2
41
+ exit 2
42
+ fi
43
+
44
+ # Block credential files
45
+ if echo "$FILE" | grep -qiE '\.aws/credentials|\.gcloud/credentials|\.azure/|/etc/shadow|\.gnupg/'; then
46
+ echo "BLOCKED: Reading credential/secret file: $FILE" >&2
47
+ exit 2
48
+ fi
49
+
50
+ # Block production env files
51
+ if echo "$FILE" | grep -qiE '\.env\.(production|prod|staging)$'; then
52
+ echo "BLOCKED: Reading production environment file: $FILE" >&2
53
+ echo " Production secrets should not be in conversation context." >&2
54
+ exit 2
55
+ fi
56
+
57
+ exit 0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cc-safe-setup",
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.",
3
+ "version": "29.6.16",
4
+ "description": "One command to make Claude Code safe. 438 example hooks + 8 built-in. 52 CLI commands. 5835 tests. Works with Auto Mode.",
5
5
  "main": "index.mjs",
6
6
  "bin": {
7
7
  "cc-safe-setup": "index.mjs"