本文目录导读:

Git 钩子(Hook)脚本非常适合在本地或服务端实施安全策略检查(如禁止提交硬编码密码、检测密钥文件、禁止敏感 API Token 等),以下是一些常见的安全策略检查实现方式。
禁止提交硬编码密码/密钥
pre-commit 钩子(客户端)
#!/bin/bash
# .git/hooks/pre-commit
# 定义需要检测的模式(正则表达式)
PATTERNS=(
"password\s*[:=]\s*['\"]?\w+['\"]?" # 通用密码
"api.?key\s*[:=]\s*['\"]?\w+['\"]?" # API Key
"secret\s*[:=]\s*['\"]?\w+['\"]?" # Secret
"token\s*[:=]\s*['\"]?\w+['\"]?" # Token
"-----BEGIN RSA PRIVATE KEY-----" # 私钥
"AKIA[0-9A-Z]{16}" # AWS Access Key
)
# 获取暂存区中的文件变更
FILES=$(git diff --cached --name-only --diff-filter=ACM)
for file in $FILES; do
# 排除一些文件类型(如 .min.js, .lock 等)
if [[ "$file" =~ \.(min\.js|lock|sum|hash)$ ]]; then
continue
fi
# 检查文件中是否包含敏感模式
for pattern in "${PATTERNS[@]}"; do
if git diff --cached -U0 "$file" | grep -qE "$pattern"; then
echo "Error: 文件 $file 包含潜在的敏感信息(匹配模式: $pattern)"
echo "请移除敏感信息后重试,或者使用 git reset 取消暂存"
exit 1
fi
done
done
exit 0
使用专门的工具(更推荐)
使用 gitleaks 工具
# .gitleaks.toml 配置文件
[whitelist]
files = [
".gitignore",
"*.md",
"*.test.js"
]
regexes = [
"^.*fake.*password.*$",
"^.*example.*key.*$"
]
#!/bin/bash
# .git/hooks/pre-commit - 集成 gitleaks
# 检查是否安装了 gitleaks
if ! command -v gitleaks &> /dev/null; then
echo "警告: 未安装 gitleaks,跳过密钥检测"
exit 0
fi
# 运行 gitleaks 检测暂存区
if ! gitleaks detect --staged --verbose --config .gitleaks.toml; then
echo "错误: 检测到潜在密钥/密码泄露,请修复后重新提交"
exit 1
fi
exit 0
文件类型与大小限制
#!/bin/bash
# .git/hooks/pre-commit - 限制文件类型和大小
MAX_SIZE_MB=50
FORBIDDEN_FILES=(
"*.exe"
"*.dll"
"*.so"
"*.dmg"
"*.pkg"
"node_modules/"
"vendor/"
)
# 检查文件大小
files=$(git diff --cached --name-only --diff-filter=ACM)
for file in $files; do
size=$(git diff --cached --name-only -z "$file" | xargs -0 stat -f%z 2>/dev/null || \
git diff --cached --name-only -z "$file" | xargs -0 ls -l | awk '{print $5}')
if [ "$size" -gt $((MAX_SIZE_MB * 1024 * 1024)) ]; then
echo "错误: 文件 $file 大于 ${MAX_SIZE_MB}MB"
exit 1
fi
done
# 检查禁止文件类型
for pattern in "${FORBIDDEN_FILES[@]}"; do
if git diff --cached --name-only | grep -qE "$pattern"; then
echo "错误: 禁止提交 ${pattern} 类型文件"
exit 1
fi
done
exit 0
提交信息安全审计
commit-msg 钩子
#!/bin/bash
# .git/hooks/commit-msg
commit_msg_file=$1
commit_msg=$(cat "$commit_msg_file")
# 禁止在提交信息中包含敏感信息
SENSITIVE_PATTERNS=(
"password"
"AKIA[A-Z0-9]{16}" # AWS Key
"sk-[A-Za-z0-9]{32}" # OpenAI key
)
for pattern in "${SENSITIVE_PATTERNS[@]}"; do
if echo "$commit_msg" | grep -qE "$pattern"; then
echo "错误: 提交信息包含敏感内容(匹配: $pattern)"
exit 1
fi
done
# 检查 JIRA 等工单号格式
JIRA_REGEX="^(feat|fix|chore)\([A-Z]+-[0-9]+\): "
if ! echo "$commit_msg" | grep -qE "$JIRA_REGEX"; then
echo "警告: 提交信息格式不符合规范(期望: feat(JIRA-123): 描述)"
fi
exit 0
服务端 hook 安全策略(更严格)
pre-receive 钩子(服务端)
#!/bin/bash
# hooks/pre-receive - 服务端强制安全检查
# 读取标准输入:<old-value> <new-value> <ref-name>
while read oldrev newrev refname; do
# 获取新提交中的文件列表
files=$(git diff --name-only "$oldrev" "$newrev" --diff-filter=ACM)
# 检查是否有 .env 文件被提交
if echo "$files" | grep -qE "\.env$"; then
echo "错误: 禁止推送 .env 文件到服务器"
exit 1
fi
# 检查是否有密钥文件
if echo "$files" | grep -qE "id_rsa|id_dsa|private.key"; then
echo "错误: 禁止推送密钥文件"
exit 1
fi
# 检查提交者身份
for commit in $(git rev-list "$newrev" --not "$oldrev"); do
author=$(git log -1 --format='%ae' "$commit")
# 检查是否使用公司邮箱
if ! echo "$author" | grep -qE "@company\.com$"; then
echo "错误: 提交 $commit 使用非公司邮箱: $author"
exit 1
fi
# 检查签名
if ! git verify-commit "$commit" &>/dev/null; then
echo "错误: 提交 $commit 未使用 GPG 签名"
exit 1
fi
done
done
exit 0
完整的 hook 管理方案
项目级 .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-added-large-files
args: ['--maxkb=500']
- id: detect-private-key
- id: check-merge-conflict
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/gitleaks/gitleaks
rev: v8.16.3
hooks:
- id: gitleaks
- repo: https://github.com/commitizen-tools/commitizen
rev: v2.42.1
hooks:
- id: commitizen
stages: [commit-msg]
- repo: local
hooks:
- id: custom-security-check
name: Custom Security Audit
entry: scripts/security-check.sh
language: script
stages: [commit]
最佳实践建议
- 分层检查:本地 hook 做基础检查,服务端 hook 做强制审核
- 性能优化:只检查暂存区文件,避免全量扫描
- 白名单机制:允许跳过某些合法文件
- 工具集成:优先使用社区成熟的工具(gitleaks、truffleHog)
- 用户反馈:提供清晰的错误信息和修复建议
- 持续更新:定期更新敏感模式库
- 结合 CI/CD:将安全钩子集成到流水线中
通过合理配置 Git 钩子,可以在代码提交前自动拦截大多数常见的安全问题,有效降低敏感信息泄露的风险。