Git钩子脚本如何检查脱敏策略

wen 实用脚本 1

本文目录导读:

Git钩子脚本如何检查脱敏策略

  1. 基本思路
  2. 通用 pre-commit 钩子脚本示例
  3. 更全面的检测模式增强
  4. 进阶:使用 pre-commit 框架
  5. 最佳实践建议
  6. 注意事项

Git 钩子脚本可以用来在提交、推送等操作前自动检查代码中是否存在潜在的敏感信息(如密码、密钥、Token、内网IP等),以下是一个实用的、用于检查脱敏策略的 pre-commit 钩子 脚本实现方案。

基本思路

  • 使用 grep 或正则表达式匹配常见的敏感信息模式
  • 扫描暂存区(staged)的文件,而非全部工作区
  • 发现敏感信息时阻止提交,并给出提示

通用 pre-commit 钩子脚本示例

将这个脚本保存为 .git/hooks/pre-commit,并赋予执行权限(chmod +x .git/hooks/pre-commit)。

#!/bin/sh
# pre-commit 钩子 - 检查敏感信息
# 定义颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo "${YELLOW}检查敏感信息中...${NC}"
# 检测敏感信息的关键词/正则表达式列表
SENSITIVE_PATTERNS=(
    # 密码相关
    "(password|passwd|pwd)\s*[=:]\s*['\"]?[^'\"\s]{4,}"
    # API密钥/Token
    "(api[_-]?key|api[_-]?secret|access[_-]?key|secret[_-]?key|private[_-]?key|token)\s*[=:]\s*['\"]?[^'\"\s]{8,}"
    # AWS密钥 (AKIA开头)
    "AKIA[0-9A-Z]{16}"
    # 私钥标记
    "-----BEGIN (RSA|DSA|EC|OPENSSH|PGP) PRIVATE KEY-----"
    # 连接字符串中的密码
    "://[^:/\s]+:[^@\s]+@"
    # 常见的秘密/密钥
    "secret\s*[=:]\s*['\"]?[^'\"\s]{8,}"
    # Google Service Account
    "type\s*:\s*service_account"
    # 内网IP (可选的,根据策略)
    "10\.\d{1,3}\.\d{1,3}\.\d{1,3}"
    "172\.(1[6-9]|2[0-9]|3[0-1])\.\d{1,3}\.\d{1,3}"
    "192\.168\.\d{1,3}\.\d{1,3}"
)
# 获取暂存区中要提交的文件列表(排除二进制文件)
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -v '.png$\|.jpg$\|.jpeg$\|.gif$\|.ico$\|.pdf$\|.exe$\|.dll$\|.so$\|.class$')
# 获取变更行(只检查新增/修改的行)
CHANGES=$(git diff --cached -U0 -- ${STAGED_FILES})
# 用于标记是否发现敏感信息
HAS_SENSITIVE=false
# 遍历每个敏感模式
for pattern in "${SENSITIVE_PATTERNS[@]}"; do
    # 使用 grep 检查 (排除注释行)
    MATCHES=$(echo "$CHANGES" | grep -n -E "$pattern" | grep -v "^[+-]?\s*#" | grep -v "^[+-]?\s*//" | grep -v "^[+-]?\s*/\*")
    if [ -n "$MATCHES" ]; then
        echo "${RED}⚠️  发现可能敏感信息: ${pattern}${NC}"
        echo "$MATCHES" | head -5
        HAS_SENSITIVE=true
    fi
done
# 自定义白名单文件(允许包含敏感信息的文件)
WHITELIST=(
    ".env.example"
    "config/sample.yaml"
)
if [ "$HAS_SENSITIVE" = true ]; then
    echo ""
    echo "${RED}═══════════════════════════════════════════════${NC}"
    echo "${RED}❌ 提交被阻止: 检测到可能的敏感信息${NC}"
    echo "${RED}请移除上述敏感数据后再提交,或使用:${NC}"
    echo "${YELLOW}  git commit --no-verify   (跳过钩子检查,不推荐)${NC}"
    echo "${RED}═══════════════════════════════════════════════${NC}"
    exit 1
fi
echo "${GREEN}✅ 敏感信息检查通过${NC}"
exit 0

更全面的检测模式增强

如果策略需要更严格的检查,可以扩展检测模式:

# 更全面的模式
SENSITIVE_PATTERNS+=(
    # JWT Token
    "eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+"
    # 各种Token/哈希
    "(ghp|gho|ghu|ghs|ghr)_[a-zA-Z0-9]{36}"  # GitHub Token
    "xox[baprs]-[a-zA-Z0-9-]{24,}"            # Slack Token
    "sk_live_[0-9a-zA-Z]{24,}"                # Stripe Live Key
    "pk_live_[0-9a-zA-Z]{24,}"                # Stripe Live Publishable Key
    # 手机号/身份证 (中国大陆,按需启用)
    # "1[3-9]\d{9}"
    # "\d{18}[\dXx]?"
)

进阶:使用 pre-commit 框架

对于团队项目,推荐使用 pre-commit 框架配合专用工具,比手动脚本更强大:

创建一个 .pre-commit-config.yaml 文件:

repos:
  - repo: https://github.com/Yelp/detect-secrets
    rev: v1.4.0
    hooks:
      - id: detect-secrets
        args: ['--baseline', '.secrets.baseline']
        exclude: '\.env\.example|tests/.*'
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
      - id: detect-private-key
      - id: check-added-large-files
        args: ['--maxkb=500']

最佳实践建议

  1. 基线文件:使用 detect-secrets 生成一个基线文件,记录已知的合法敏感信息,避免误报
  2. 分级策略
    • 硬编码密码/密钥 → 立即阻止
    • 内网IP/域名 → 警告但不阻止
    • 测试数据 → 白名单过滤
  3. 输出友好:错误信息要明确告诉开发者:哪个文件 + 哪一行 + 什么类型

注意事项

  • 脚本只能检查新增的行,无法检测通过 git mv 重命名而内容未变的文件
  • 对于大型二进制文件(如 SQLite 数据库、图片等),应使用 git lfs 管理,脚本中排除检查
  • 定期更新模式库,防御新的泄露风险(如新出现的安全令牌格式)

将这个脚本与 CI/CD 流水线中的扫描结合,可以构建前后端双层防线。

抱歉,评论功能暂时关闭!