Skip to content

Commit 83f6a6e

Browse files
committed
chore: add pre-commit hook to prevent sensitive file commits
- Whitelist approach: only known safe extensions allowed (.rs, .toml, .yml, etc.) - Block sensitive patterns (.env, .key, .pem, secrets, credentials) - Warn but allow .md files - Check only NEW files, modifications to tracked files always allowed - Block large files (>5MB) with warning - Run cargo fmt check on Rust files - Update CONTRIBUTING.md with hook setup instructions
1 parent c38f5f7 commit 83f6a6e

File tree

2 files changed

+145
-0
lines changed

2 files changed

+145
-0
lines changed

.githooks/pre-commit

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#!/bin/bash
2+
# Pre-commit hook to prevent accidental commits of sensitive files
3+
# Enable: git config core.hooksPath .githooks
4+
5+
set -e
6+
7+
RED='\033[0;31m'
8+
YELLOW='\033[1;33m'
9+
GREEN='\033[0;32m'
10+
NC='\033[0m'
11+
12+
# Allowed file extensions (whitelist)
13+
ALLOWED_EXTENSIONS=(
14+
'\.rs$'
15+
'\.toml$'
16+
'\.lock$'
17+
'\.yml$'
18+
'\.yaml$'
19+
'\.json$'
20+
'\.sh$'
21+
'\.html$'
22+
'\.css$'
23+
'\.js$'
24+
'\.gitignore$'
25+
'\.dockerignore$'
26+
'Dockerfile$'
27+
'LICENSE$'
28+
'Makefile$'
29+
)
30+
31+
# Extensions that trigger a warning (not blocked)
32+
WARN_EXTENSIONS=(
33+
'\.md$'
34+
)
35+
36+
# Always blocked patterns (regardless of extension)
37+
BLOCKED_PATTERNS=(
38+
'\.env$'
39+
'\.env\.'
40+
'\.key$'
41+
'\.pem$'
42+
'\.p12$'
43+
'\.pfx$'
44+
'\.htpasswd$'
45+
'secret'
46+
'credential'
47+
'password'
48+
'\.bak$'
49+
'\.swp$'
50+
'\.swo$'
51+
'node_modules/'
52+
'target/debug/'
53+
'\.DS_Store'
54+
)
55+
56+
# Get staged files (only NEW files, not already tracked)
57+
STAGED_FILES=$(git diff --cached --name-only --diff-filter=A)
58+
59+
if [ -z "$STAGED_FILES" ]; then
60+
# No new files, only modifications to existing - allow
61+
exit 0
62+
fi
63+
64+
# Build patterns
65+
ALLOWED_PATTERN=$(IFS='|'; echo "${ALLOWED_EXTENSIONS[*]}")
66+
WARN_PATTERN=$(IFS='|'; echo "${WARN_EXTENSIONS[*]}")
67+
BLOCKED_PATTERN=$(IFS='|'; echo "${BLOCKED_PATTERNS[*]}")
68+
69+
# Check for blocked patterns first
70+
BLOCKED_FILES=$(echo "$STAGED_FILES" | grep -iE "$BLOCKED_PATTERN" || true)
71+
72+
if [ -n "$BLOCKED_FILES" ]; then
73+
echo -e "${RED}BLOCKED: Suspicious files detected in commit${NC}"
74+
echo ""
75+
echo -e "${YELLOW}Files:${NC}"
76+
echo "$BLOCKED_FILES" | sed 's/^/ - /'
77+
echo ""
78+
echo "If intentional, use: git commit --no-verify"
79+
exit 1
80+
fi
81+
82+
# Check for files with unknown extensions
83+
UNKNOWN_FILES=""
84+
WARN_FILES=""
85+
86+
while IFS= read -r file; do
87+
[ -z "$file" ] && continue
88+
89+
if echo "$file" | grep -qE "$BLOCKED_PATTERN"; then
90+
continue # Already handled above
91+
elif echo "$file" | grep -qE "$WARN_PATTERN"; then
92+
WARN_FILES="$WARN_FILES$file"$'\n'
93+
elif ! echo "$file" | grep -qE "$ALLOWED_PATTERN"; then
94+
UNKNOWN_FILES="$UNKNOWN_FILES$file"$'\n'
95+
fi
96+
done <<< "$STAGED_FILES"
97+
98+
# Warn about .md files
99+
if [ -n "$WARN_FILES" ]; then
100+
echo -e "${YELLOW}WARNING: Markdown files in commit:${NC}"
101+
echo "$WARN_FILES" | sed '/^$/d' | sed 's/^/ - /'
102+
echo ""
103+
fi
104+
105+
# Block unknown extensions
106+
if [ -n "$UNKNOWN_FILES" ]; then
107+
echo -e "${RED}BLOCKED: Files with unknown extensions:${NC}"
108+
echo "$UNKNOWN_FILES" | sed '/^$/d' | sed 's/^/ - /'
109+
echo ""
110+
echo "Allowed extensions: rs, toml, lock, yml, yaml, json, sh, html, css, js, md"
111+
echo "If intentional, use: git commit --no-verify"
112+
exit 1
113+
fi
114+
115+
# Check for large files (>5MB)
116+
LARGE_FILES=$(echo "$STAGED_FILES" | while read f; do
117+
if [ -f "$f" ]; then
118+
size=$(stat -f%z "$f" 2>/dev/null || stat -c%s "$f" 2>/dev/null || echo 0)
119+
if [ "$size" -gt 5242880 ]; then
120+
echo "$f ($(numfmt --to=iec $size 2>/dev/null || echo "${size}B"))"
121+
fi
122+
fi
123+
done)
124+
125+
if [ -n "$LARGE_FILES" ]; then
126+
echo -e "${YELLOW}WARNING: Large files (>5MB) in commit:${NC}"
127+
echo "$LARGE_FILES" | sed 's/^/ - /'
128+
echo ""
129+
fi
130+
131+
# Run cargo fmt check if Rust files changed
132+
if git diff --cached --name-only | grep -q '\.rs$'; then
133+
if command -v cargo &> /dev/null; then
134+
if ! cargo fmt --check &> /dev/null; then
135+
echo -e "${RED}BLOCKED: cargo fmt check failed${NC}"
136+
echo "Run: cargo fmt"
137+
exit 1
138+
fi
139+
fi
140+
fi
141+
142+
exit 0

CONTRIBUTING.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ Thank you for your interest in contributing to NORA!
1414
# Install Rust (if needed)
1515
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
1616

17+
# Enable pre-commit hooks (important!)
18+
git config core.hooksPath .githooks
19+
1720
# Build
1821
cargo build
1922

0 commit comments

Comments
 (0)