Repository navigation
Expand file tree
/
Copy pathpre-commit
More file actions
126 lines (110 loc) · 3.92 KB
/
Copy pathpre-commit
File metadata and controls
126 lines (110 loc) · 3.92 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
#!/bin/bash
# セキュリティチェック用 pre-commit フック
# クライアントサイドに機密情報が含まれていないかチェック
echo ""
echo "🔍 セキュリティチェック実行中..."
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# エラーカウンター
ERROR_COUNT=0
# 機密情報パターン
declare -A PATTERNS=(
["シークレットキー(Stripe Live)"]="sk_live_[A-Za-z0-9]{24,}"
["シークレットキー(Stripe Test)"]="sk_test_[A-Za-z0-9]{24,}"
["Webhook署名シークレット"]="whsec_[A-Za-z0-9]{32,}"
["パスワード"]="(password|passwd|pwd)\s*[:=]\s*['\"][^'\"]{3,}['\"]"
["APIシークレット"]="api[_-]?secret\s*[:=]\s*['\"][^'\"]{3,}['\"]"
["プライベートキー"]="-----BEGIN (RSA |)PRIVATE KEY-----"
["アクセストークン(GitHub)"]="ghp_[A-Za-z0-9]{36,}"
["AWSアクセスキー"]="AKIA[0-9A-Z]{16}"
)
# チェック対象ファイル(クライアントサイドのみ)
CLIENT_SIDE_FILES=(
"*.html"
"*.js"
"*.jsx"
"*.ts"
"*.tsx"
"*.css"
"*.scss"
"*.vue"
)
# ステージングされたファイルを取得
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
if [ -z "$STAGED_FILES" ]; then
echo "✅ コミット対象のファイルがありません"
exit 0
fi
# 各パターンでチェック
for description in "${!PATTERNS[@]}"; do
pattern="${PATTERNS[$description]}"
for file in $STAGED_FILES; do
# クライアントサイドファイルのみチェック
is_client_side=false
for ext in "${CLIENT_SIDE_FILES[@]}"; do
if [[ $file == $ext ]] || [[ $file == *"/"$ext ]]; then
is_client_side=true
break
fi
done
# api/ ディレクトリは除外(サーバーサイド)
if [[ $file == api/* ]]; then
is_client_side=false
fi
if [ "$is_client_side" = true ]; then
# ファイルの内容をチェック
if git show ":$file" | grep -qE "$pattern"; then
echo ""
echo "❌ エラー: $description が検出されました"
echo " ファイル: $file"
echo " パターン: $pattern"
echo ""
ERROR_COUNT=$((ERROR_COUNT + 1))
fi
fi
done
done
# .env ファイルのチェック
if echo "$STAGED_FILES" | grep -qE "^\.env$"; then
echo ""
echo "❌ エラー: .env ファイルをコミットしようとしています"
echo " .env ファイルは機密情報を含むため、コミットできません"
echo " 代わりに .env.example を使用してください"
echo ""
ERROR_COUNT=$((ERROR_COUNT + 1))
fi
# .env.local などのチェック
if echo "$STAGED_FILES" | grep -qE "\.env\."; then
if ! echo "$STAGED_FILES" | grep -qE "\.env\.example$"; then
echo ""
echo "❌ エラー: 環境変数ファイルをコミットしようとしています"
echo " 検出されたファイル:"
echo "$STAGED_FILES" | grep "\.env\." | sed 's/^/ - /'
echo ""
ERROR_COUNT=$((ERROR_COUNT + 1))
fi
fi
# node_modules のチェック
if echo "$STAGED_FILES" | grep -q "node_modules/"; then
echo ""
echo "⚠️ 警告: node_modules/ 内のファイルをコミットしようとしています"
echo " .gitignore に node_modules/ が含まれていることを確認してください"
echo ""
fi
# 結果表示
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [ $ERROR_COUNT -eq 0 ]; then
echo "✅ セキュリティチェック完了 - 問題なし"
echo ""
exit 0
else
echo "❌ セキュリティチェック失敗 - $ERROR_COUNT 件のエラー"
echo ""
echo "修正方法:"
echo "1. 検出された機密情報を削除"
echo "2. 環境変数 (process.env.XXX) を使用"
echo "3. サーバーサイド (api/) で処理"
echo ""
echo "詳細は SECURITY_RULES.md を参照してください"
echo ""
exit 1
fi