ワンクリックで
opensource-preflight
开源发布前综合扫描——一次调用检测密钥泄露、个人信息、内部引用、许可证合规、规范文件缺失和 Git 历史泄露,输出结构化报告并给出修复建议。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
开源发布前综合扫描——一次调用检测密钥泄露、个人信息、内部引用、许可证合规、规范文件缺失和 Git 历史泄露,输出结构化报告并给出修复建议。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | opensource-preflight |
| description | 开源发布前综合扫描——一次调用检测密钥泄露、个人信息、内部引用、许可证合规、规范文件缺失和 Git 历史泄露,输出结构化报告并给出修复建议。 |
当用户准备将代码仓库开源发布,或要求进行开源前检查、安全扫描、合规检查时触发此 skill。
| 参数 | 可选值 | 默认值 | 说明 |
|---|---|---|---|
| mode | quick / standard / strict | standard | 扫描深度 |
| path | 目录路径 | 当前工作目录 | 扫描目标 |
| exclude | glob 列表 | node_modules, vendor, *.min.js | 排除路径 |
.opensource-preflight.yml 配置(如有)opensource-preflight-report.md| 等级 | 含义 | 结论影响 |
|---|---|---|
| CRITICAL | 必须修复才能开源 | ✗ 未就绪 |
| HIGH | 强烈建议修复 | ⚠ 需审查 |
| MEDIUM | 建议修复 | ✓ 就绪(附建议) |
| LOW | 可选优化 | ✓ 就绪 |
等级: 全部 CRITICAL
先运行以下命令检测外部工具:
which gitleaks 2>/dev/null && echo "GITLEAKS_AVAILABLE=true"
which trufflehog 2>/dev/null && echo "TRUFFLEHOG_AVAILABLE=true"
如果 gitleaks 可用:
gitleaks detect --source . --no-git --report-format json --report-path /tmp/gitleaks-report.json
如果 trufflehog 可用(作为补充):
trufflehog filesystem . --json > /tmp/trufflehog-report.json
解析 JSON 报告,提取:文件路径、行号、规则名称、匹配内容(脱敏显示前4后4字符)。
依次用 Grep 工具搜索以下模式(排除 exclude 路径):
| 类别 | 正则模式 |
|---|---|
| AWS Access Key | AKIA[0-9A-Z]{16} |
| AWS Secret | aws_secret_access_key\s*[=:]\s*['"]?[A-Za-z0-9/+=]{40} |
| GCP API Key | AIza[0-9A-Za-z\-_]{35} |
| Azure | DefaultEndpointsProtocol=https;AccountName= |
| GitHub Token | (ghp|gho|ghs|github_pat)_[A-Za-z0-9_]{36,} |
| Stripe Live | (sk|pk)_live_[A-Za-z0-9]{24,} |
| Slack Token | xox[bpras]-[A-Za-z0-9\-]{10,} |
| 私钥 | -----BEGIN (RSA|EC|DSA|OPENSSH|PGP) PRIVATE KEY----- |
| 数据库连接串 | (mysql|postgres|mongodb(\+srv)?):\/\/[^:]+:[^@]+@ |
| 通用密码赋值 | (password|passwd|pwd|secret)\s*[=:]\s*['"][^'"]{8,}['"] |
| 高熵字符串 | 在变量赋值上下文中出现的 40+ 字符 Base64/Hex 串 |
对每个匹配结果,检查是否命中以下白名单,命中则排除:
xxx、your-.*-here、<.*>、example、changeme、TODO.example、.sample、.templatesk_test_、pk_test_AAAAAAA...)每个发现记录为:
{layer: 1, severity: "CRITICAL", category: "密钥", file: "path", line: N, summary: "AWS Access Key 泄露", detail: "AKIA****XXXX", fix: "移至环境变量,添加到 .gitignore"}
用 Grep 工具依次搜索:
| 类别 | 正则模式 | 等级 |
|---|---|---|
| 中国身份证 | \b\d{17}[\dXx]\b | CRITICAL |
| 美国 SSN | \b\d{3}-\d{2}-\d{4}\b | CRITICAL |
| 银行卡号 | \b[3-6]\d{12,18}\b(后续 Luhn 校验) | CRITICAL |
| 中国手机号 | \b1[3-9]\d{9}\b | HIGH |
| 国际电话 | \+\d{7,15} | HIGH |
| 邮箱地址 | [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} | HIGH |
| 公网 IPv4 | \b(?!10\.|127\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b | HIGH |
| 中文地址 | 含"省""市""区""街""号"的连续中文文本 | MEDIUM |
对每个匹配结果,根据上下文调整等级:
test/、mock/、fixture/、__tests__/ → 降一级但保留package.json 的 author/contributors 字段 → 标记为 LOW(预期行为)console.log、logger.、log.)→ 附加"运行时泄露风险"警告// TODO 或 # FIXME 注释中 → 保持原等级排除以下情况:
example.com、test.com、test.org、localhost、placeholder.com13800138000、10000000000000-00-0000、123-45-6789对疑似银行卡号,执行以下验证:
{layer: 2, severity: "HIGH", category: "PII", file: "path", line: N, summary: "真实手机号", detail: "138****1234", fix: "替换为假数据或移至环境配置"}
用 Grep 工具依次搜索:
| 类别 | 正则模式 | 等级 |
|---|---|---|
| 内网域名 | [a-zA-Z0-9-]+\.(internal|local|corp|intranet|private)\b | HIGH |
| RFC 1918 URL | https?:\/\/(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.)\d{1,3}\.\d{1,3} | HIGH |
| K8s 内部服务 | [a-z-]+\.svc\.cluster\.local | MEDIUM |
| 内部工具 | (jira|confluence|gitlab|jenkins|grafana|kibana)\.[a-zA-Z0-9-]+\.(com|net|org|io) | MEDIUM |
| 硬编码主机名 | (prod|staging|dev|qa)-(db|redis|api|web|app|cache)-\d+ | HIGH |
| 内部邮件组 | (team|dev|eng|ops|infra)-[a-z]+@ | MEDIUM |
| VPN/内网路径 | (vpn|intranet|internal)\.[a-zA-Z] | HIGH |
如果 .opensource-preflight.yml 中定义了 internal_domains,额外匹配:
.example、.sample、.template 文件中 → 降为 LOWlocalhost:3000 类开发端口出现在 README/文档中 → LOW*.yaml、*.yml(Helm/K8s manifests)→ MEDIUM(预期但仍标记)docker-compose.yml 的 service 名 → LOW(本地开发配置){layer: 3, severity: "HIGH", category: "内部引用", file: "path", line: N, summary: "内网域名泄露", detail: "api.mycompany.internal", fix: "替换为环境变量或配置文件,从代码中移除硬编码"}
模式要求: standard 及以上
用 Glob 工具搜索:LICENSE*、COPYING*、LICENCE*
读取项目 manifest 文件(package.json、Cargo.toml、pyproject.toml、setup.py、go.mod),检查:
license 字段是否存在Node 项目:
npx license-checker --json --production > /tmp/licenses.json 2>/dev/null
如果命令不可用,读取 node_modules/*/package.json 的 license 字段(仅扫描直接依赖)。
Python 项目:
pip-licenses --format=json > /tmp/licenses.json 2>/dev/null
如果命令不可用,从 requirements.txt 列出依赖名,逐个检查已知 license。
Rust 项目:
cargo-license --json > /tmp/licenses.json 2>/dev/null
兼容性判定矩阵:
项目 License 为 MIT 时,以下依赖 license 不兼容(HIGH):
- GPL-2.0, GPL-3.0, AGPL-3.0
项目 License 为 Apache-2.0 时,以下不兼容(HIGH):
- GPL-2.0, AGPL-3.0
项目 License 为 GPL-3.0 时,以下不兼容(HIGH):
- 专有许可 (proprietary)
需要注意但不阻断(MEDIUM):
- LGPL(需确认链接方式)
- MPL-2.0(文件级 copyleft)
检查 LICENSE 文件中的年份,如果比当前年份早 2 年以上 → LOW
{layer: 4, severity: "HIGH", category: "许可证", file: "package.json", line: null, summary: "依赖 license 不兼容", detail: "lodash-gpl (GPL-3.0) 与项目 MIT 不兼容", fix: "寻找替代包或更换项目 license"}
模式要求: standard 及以上
用 Glob 工具检查以下文件是否存在:
| 文件 | standard | strict | 缺失等级 |
|---|---|---|---|
| README.md | 必须 | 必须 | MEDIUM |
| .gitignore | 必须 | 必须 | MEDIUM |
| CONTRIBUTING.md | 建议 | 必须 | LOW / MEDIUM |
| CODE_OF_CONDUCT.md | 可选 | 建议 | LOW |
| CHANGELOG.md | 可选 | 建议 | LOW |
| SECURITY.md | 建议 | 必须 | LOW / MEDIUM |
| .github/ISSUE_TEMPLATE/ | 可选 | 建议 | LOW |
| .github/PULL_REQUEST_TEMPLATE.md | 可选 | 建议 | LOW |
读取 README.md 内容,检查:
检测项目语言(通过文件扩展名),验证 .gitignore 是否覆盖:
| 语言标志 | 必须忽略 |
|---|---|
*.js/*.ts | node_modules/、dist/、.env* |
*.py | __pycache__/、*.pyc、.venv/、.env* |
*.rs | target/、.env* |
*.go | vendor/(如使用)、.env* |
| 通用 | .DS_Store、Thumbs.db、*.log、.idea/、.vscode/(settings) |
缺少条目 → LOW(建议添加)
读取 manifest 文件,检查是否缺少:
description → LOWrepository / homepage → LOWprivate: true 仍存在 → MEDIUM(开源应移除){layer: 5, severity: "MEDIUM", category: "规范", file: "README.md", line: null, summary: "README 缺少安装说明", detail: "未找到 install/setup 相关段落", fix: "添加 ## 安装 段落,说明如何安装和运行项目"}
模式要求: standard(最近 50 次 commit)/ strict(全部历史) quick 模式跳过此层。
which trufflehog 2>/dev/null && echo "TRUFFLEHOG_AVAILABLE=true"
which gitleaks 2>/dev/null && echo "GITLEAKS_AVAILABLE=true"
如果 trufflehog 可用:
trufflehog git file://. --only-verified --json > /tmp/trufflehog-history.json
如果 gitleaks 可用:
gitleaks detect --source . --log-opts="--all" --report-format json --report-path /tmp/gitleaks-history.json
根据模式确定范围:
--all执行以下扫描命令:
# 检查被删除的敏感文件
git log --all --diff-filter=D --name-only --pretty=format:"%H %ai" -- '*.env' '*.env.*' '*.pem' '*.key' '*.p12' '*.pfx' 'credentials.json' '*secret*'
# 搜索历史中的密钥模式
git log --all -p -S "AKIA" --pretty=format:"COMMIT:%H DATE:%ai" | head -200
git log --all -p -S "BEGIN RSA PRIVATE KEY" --pretty=format:"COMMIT:%H DATE:%ai" | head -200
git log --all -p -S "password" --pretty=format:"COMMIT:%H DATE:%ai" -- '*.env' '*.yml' '*.yaml' '*.json' '*.toml' | head -200
git log --all --format="%ae" | sort -u
检查是否有内部邮箱(匹配 internal_domains 配置,或通用模式如含 corp、internal 的域名)→ MEDIUM
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | awk '/^blob/ && $3 > 10485760 {print $3, $4}'
发现 >10MB 文件 → LOW
对历史泄露问题,给出具体修复命令:
清理敏感文件历史:
# 推荐:git-filter-repo(需 pip install git-filter-repo)
git filter-repo --path <敏感文件路径> --invert-paths
# 备选:BFG Repo-Cleaner
bfg --delete-files <文件名> .
git reflog expire --expire=now --all && git gc --prune=now
重写作者邮箱:
# 创建 mailmap 文件
echo "New Name <public@email.com> Old Name <internal@corp.com>" > .mailmap
git filter-repo --mailmap .mailmap
全新开源(从内部 repo 迁移):
# 压缩为干净的 initial commit
git checkout --orphan clean-main
git add -A
git commit -m "Initial open-source release"
git branch -D main
git branch -m main
{layer: 6, severity: "CRITICAL", category: "历史", file: null, line: null, summary: "历史 commit 中发现 AWS 密钥", detail: "commit a3f2c1d (2025-03-14) 曾包含 AKIA****XXXX", fix: "使用 git-filter-repo 清理历史,或 squash 为干净的 initial commit"}
扫描完成后,按以下格式输出终端摘要:
═══════════════════════════════════════════════
Opensource Preflight 扫描报告 — 模式: {mode}
═══════════════════════════════════════════════
CRITICAL {n} 个问题(必须修复才能开源)
HIGH {n} 个问题
MEDIUM {n} 个问题
LOW {n} 个问题
─── CRITICAL ───────────────────────────────────
[{category}] {file}:{line} — {summary}
...
─── HIGH ───────────────────────────────────────
[{category}] {file}:{line} — {summary}
...
─── MEDIUM ─────────────────────────────────────
[{category}] {file}:{line} — {summary}
...
═══════════════════════════════════════════════
结论: {verdict}
完整报告: ./opensource-preflight-report.md
═══════════════════════════════════════════════
✗ 未就绪 — 不可开源发布⚠ 需审查 — 建议修复后再发布✓ 就绪(附建议)✓ 完全就绪将完整报告写入项目根目录 opensource-preflight-report.md,结构如下:
# Opensource Preflight 扫描报告
**扫描时间:** YYYY-MM-DD HH:mm
**扫描模式:** {mode}
**扫描路径:** {path}
**结论:** {verdict}
## 摘要
| 等级 | 数量 |
|------|------|
| CRITICAL | N |
| HIGH | N |
| MEDIUM | N |
| LOW | N |
## 第 1 层:密钥与凭证
| # | 等级 | 文件 | 行 | 问题 | 修复建议 |
|---|------|------|-----|------|----------|
| 1 | CRITICAL | src/config.ts | 14 | 硬编码数据库密码 | 移至环境变量 |
## 第 2 层:个人信息
(同上表格结构)
## 第 3 层:内部引用
(同上表格结构)
## 第 4 层:许可证合规
(同上表格结构)
## 第 5 层:开源规范文件
(同上表格结构)
## 第 6 层:Git 历史
(同上表格结构)
## 推荐操作
按优先级排列的修复步骤:
1. **[CRITICAL]** 立即移除 `.env.production` 并添加到 .gitignore
2. **[CRITICAL]** 清理 git 历史中的 AWS 密钥
3. **[HIGH]** 替换测试数据中的真实手机号为假数据
...
扫描完成并输出报告后,针对 CRITICAL 和 HIGH 级别问题,逐个给出修复方案并询问用户:
以下操作可在用户确认后自动执行:
.env* 文件添加到 .gitignoreprocess.env.DB_PASSWORD)package.json 中的 private: true以下操作只提供命令,不自动执行:
git-filter-repo)对每个可自动修复的问题,询问:
"发现 {N} 个可自动修复的问题。是否逐个确认修复?(Y/n)"
如果用户同意,逐个展示修复内容并执行。每次修复后提交一个 commit。
| 扫描层 | quick | standard | strict |
|---|---|---|---|
| 1. 密钥与凭证 | ✓ | ✓ | ✓ |
| 2. 个人信息 | ✓ | ✓ | ✓ |
| 3. 内部引用 | ✓ | ✓ | ✓ |
| 4. 许可证合规 | ✗ | ✓ | ✓(含兼容性矩阵) |
| 5. 开源规范 | ✗ | ✓ | ✓(含全部可选文件) |
| 6. Git 历史 | ✗ | 最近 50 次 commit | 全部历史 |