GP-commits/Git-Secrets

GitHub: GP-commits/Git-Secrets

这款 Python 命令行工具能深入扫描 GitHub 仓库的提交历史及当前代码,快速发现意外泄露的 API 密钥和敏感令牌。

Stars: 120 | Forks: 17

bytedance%2Fdeer-flow | Trendshift

Screenshot_2026-04-06_151021-removebg-preview

一款强大的 CLI 工具,用于扫描 GitHub 仓库中意外提交的机密信息——API 密钥、令牌、密码、私钥等。

Like a digital metal detector for your codebase. Find what shouldn't be public before someone else does.

CLI Demo

## ⚡ 功能 ## 之前的更新 - TURBO 并行扫描 —— 使用新的 --jobs 标志同时扫描多个仓库(提速 5 倍) - 高级降噪 —— 自动跳过 venv、site-packages 和其他库文件夹 - 智能去重 —— 智能地优先处理特定类型的机密信息而非通用类型 - 交互式命令指南 —— 使用新的 --guide 标志获取所有功能的分类概览 - 20 多种机密模式 —— AWS、GitHub、Google、Stripe、Slack、Discord、Telegram、JWT、SSH 密钥、数据库 URI 等 - 完整提交历史扫描 —— 检测已提交但随后被删除的机密信息 - 可选 PAT 支持 —— 扫描私有仓库或绕过速率限制 - 清晰的 ASCII 报告 —— 极易阅读的审计日志,无表情符号或冗余命中信息的干扰 - JSON 导出 —— 适用于 CI/CD 流水线的机器可读输出 - Fork 过滤 —— 默认跳过 fork 以专注于原始代码 - CI 友好 —— 发现机密信息时以代码 1 退出 ## 🏗️ 架构 GIT secrets scanning flowchart ### 工作原理 1. **输入** — 你提供一个 GitHub 用户名或组织名称 2. **发现** — 工具查询 GitHub API 以获取所有仓库(分页),并过滤掉 fork 3. **克隆** — 每个仓库都被克隆到一个临时目录(快速模式下使用 `--depth 1`) 4. **扫描** — 运行两次扫描: - **文件扫描**:遍历工作树,读取每个文本文件,并根据 20 多种正则表达式模式进行匹配 - **历史扫描** *(默认)*:运行 `git log -p --all` 以检查完整提交历史中的每个新增行 5. **去重** — 合并两次扫描中相同的发现结果 6. **报告** — 打印彩色终端报告;导出可选的 JSON 文件 7. **清理** — 自动删除临时克隆目录 ## 安装 ### 前置条件 - **Python 3.8+** — [下载 Python](https://www.python.org/downloads/) - **Git** — [下载 Git](https://git-scm.com/downloads) ### 设置 ``` # 1. Clone 或下载此 project git clone https://github.com/your-username/git-secrets-scanner.git cd git-secrets-scanner # 2. (推荐)创建一个 virtual environment python -m venv venv # On Windows venv\Scripts\activate # On macOS/Linux source venv/bin/activate # 3. 安装 dependencies pip install -r requirements.txt ``` ### 依赖 | Package | Purpose | |---------|---------| | `requests` | GitHub API 调用 | | `colorama` | 跨平台彩色终端输出 | ## 🚀 使用方法 ### 基本扫描(完整历史 —— 推荐) ``` python scanner.py ``` 这会克隆每个非 fork 的仓库,并扫描当前文件**以及完整的提交历史**中的机密信息。这是最彻底的模式 —— 它可以捕获已提交但随后被删除的机密信息。 ### 快速模式(仅最新提交) ``` python scanner.py --fast ``` 仅扫描文件的当前状态。速度更快,但无法捕获已删除的机密信息。 ### 使用 GitHub Personal Access Token ``` python scanner.py --token ghp_your_token_here ``` 使用 PAT 来: - 扫描你拥有的**私有仓库** - 避免 GitHub API **速率限制**(未认证 60 次/小时 → 使用令牌 5,000 次/小时) ### 将结果导出为 JSON ``` python scanner.py --output report.json ``` 生成结构化的 JSON 文件,以便与 CI/CD 流水线或仪表板集成。 ### 包含 fork 的仓库 ``` python scanner.py --include-forks ``` 默认情况下,为了专注于原始代码,会排除 fork。使用此标志可包含它们。 ### 详细输出 ``` python scanner.py --verbose ``` 显示扫描的每个文件和提交的详细进度。 ### 不安全的机密显示 ``` python scanner.py --unsafe-show-secrets --yes ``` ### 所有选项组合 ``` python scanner.py myorg \ --token ghp_xxxxxxxxxxxx \ --fast \ --output report.json \ --include-forks \ --verbose ``` ### 命令行参考 ``` usage: scanner.py [-h] [--token TOKEN] [--fast] [--output OUTPUT] [--include-forks] [--unsafe-show-secrets] [--yes] [--verbose] [--jobs JOBS] [--guide] username positional arguments: username GitHub username or organization name options: -h, --help show this help message and exit --token, -t TOKEN GitHub Personal Access Token (optional) --fast, -f Fast mode: scan only the latest commit (skip history) --output, -o OUTPUT Export results as JSON to this file path --include-forks Include forked repositories (excluded by default) --unsafe-show-secrets Show the full unredacted secrets in the output --yes, -y Bypass interactive confirmation for --unsafe-show-secrets --verbose, -v Show detailed progress output --jobs, -j JOBS Number of concurrent repo scans (default: 4) --guide Show the visual command guide ``` ## 🔍 检测到的机密类型 | Category | Secret Type | Example Pattern | |----------|------------|-----------------| | **AWS** | Access Key ID | `AKIA...` (20 chars) | | **AWS** | Secret Access Key | `aws_secret_access_key = ...` | | **GitHub** | Personal Access Token (classic) | `ghp_...` | | **GitHub** | Fine-grained PAT | `github_pat_...` | | **GitHub** | OAuth Access Token | `gho_...` | | **Google** | API Key | `AIza...` (39 chars) | | **Google** | OAuth Client Secret | `client_secret = ...` | | **Stripe** | Secret Key | `sk_live_...` | | **Stripe** | Publishable Key | `pk_live_...` | | **Slack** | Bot Token | `xoxb-...-...-...` | | **Slack** | Webhook URL | `https://hooks.slack.com/services/...` | | **Discord** | Bot Token | `M...` / `N...` (base64 format) | | **Telegram** | Bot Token | `123456789:ABC-DEF...` | | **SendGrid** | API Key | `SG....` | | **Mailgun** | API Key | `key-...` (32 hex chars) | | **Twilio** | API Key | `SK...` (32 hex chars) | | **Heroku** | API Key | `heroku_api_key = ...` (UUID) | | **NPM** | Access Token | `npm_...` | | **Azure** | Storage Account Key | `AccountKey = ...` (88 chars) | | **Firebase** | Cloud Messaging Key | `AAAA...:...` | | **Auth** | JSON Web Token (JWT) | `eyJ...eyJ...` | | **Auth** | Private Key (RSA/DSA/EC/SSH) | `-----BEGIN ... PRIVATE KEY-----` | | **Database** | Connection String | `mongodb://...`, `postgres://...` | | **Generic** | Password/Secret assignments | `password = "..."`, `api_key = "..."` | ## 📊 示例输出 ``` ██████╗ ██╗████████╗ ███████╗███████╗ ██████╗██████╗ ███████╗████████╗███████╗ ██╔════╝ ██║╚══██╔══╝ ██╔════╝██╔════╝██╔════╝██╔══██╗██╔════╝╚══██╔══╝██╔════╝ ██║ ███╗██║ ██║ ███████╗█████╗ ██║ ██████╔╝█████╗ ██║ ███████╗ ██║ ██║██║ ██║ ╚════██║██╔══╝ ██║ ██╔══██╗██╔══╝ ██║ ╚════██║ ╚██████╔╝██║ ██║ ███████║███████╗╚██████╗██║ ██║███████╗ ██║ ███████║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚══════╝ [*] Fetching repositories for @your-username … [✓] Found 12 repositories (forks excluded). [*] [1/12] Cloning my-project … [SECRET] 2 potential secret(s) in current files ════════════════════════════════════════════════════════════════════════ SCAN REPORT — @your-username ════════════════════════════════════════════════════════════════════════ Repositories scanned : 12 Files scanned : 347 Commits scanned : 1203 Duration : 42.3s 🔑 2 potential secret(s) found! ┌─ my-project (2 finding(s)) ├── AWS Access Key ID │ config/settings.py:L14 [file] │ AKIAIO******************** │ └── Generic Secret Assignment .env.example:L3 [file] DB_PASSWORD="sup3r_******************** ``` ### JSON 导出结构 ``` { "username": "your-username", "repos_scanned": 12, "files_scanned": 347, "commits_scanned": 1203, "scan_duration_seconds": 42.3, "total_findings": 2, "findings": [ { "repo": "my-project", "file": "config/settings.py", "line_number": 14, "secret_type": "AWS Access Key ID", "snippet": "AKIAIO********************", "source": "file" } ], "errors": [] } ``` ## 🔧 配置 ### `scanner.py` 中的可调常量 | Constant | Default | Description | |----------|---------|-------------| | `MAX_FILE_SIZE` | 2 MB | 跳过大于此值的文件 | | `REPOS_PER_PAGE` | 100 | GitHub API 分页大小 | | `BINARY_EXTENSIONS` | 40+ types | 要跳过的文件扩展名 | | `SKIP_DIRS` | `.git`, `node_modules`, etc. | 要完全忽略的目录 | ### 添加自定义机密模式 在 `scanner.py` 中的 `SECRET_PATTERNS` 列表添加新模式: ``` SECRET_PATTERNS.append(( "My Custom Token", re.compile(r"\b(myapp_[A-Za-z0-9]{32})\b") )) ``` ## 🔄 CI/CD 集成 当发现机密信息时,扫描器返回**退出代码 1**,这使其易于集成到 CI 流水线中: ### GitHub Actions 示例 ``` name: Secret Scan on: [push] jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.12' - run: pip install requests colorama - run: python scanner.py ${{ github.repository_owner }} --fast --output report.json env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - uses: actions/upload-artifact@v4 if: failure() with: name: secret-scan-report path: report.json ``` ## ⚠️ 法律与道德声明 ## 🤝 贡献 1. Fork 该仓库 2. 创建一个功能分支 (`git checkout -b feature/new-pattern`) 3. 添加你的更改 4. 针对你自己的仓库进行测试 5. 提交一个 pull request ### 贡献思路 - 添加更多机密模式(Cloudflare、DigitalOcean 等) - `.gitsecretsignore` 文件用于抑制误报 - Webhook 通知(Slack、Discord、电子邮件) - Pre-commit hook 集成 - HTML 报告生成 ## 📝 许可证 本项目在 MIT 许可证下获得许可。有关详细信息,请参阅 [LICENSE](LICENSE)。

专为关注安全的开发者用心打造。

标签:API密钥, DevSecOps, Git扫描, LNA, Python, Secrets Detection, Token检测, 上游代理, 二进制发布, 云安全监控, 代码审查, 安全扫描, 密码检测, 开源工具, 无后门, 时序注入, 私钥管理, 结构化查询, 网络安全, 网络安全研究, 自动化安全, 逆向工具, 隐私保护, 静态分析