security: widen verifier (openssh/hyphenated-sk/ctx7sk/credential-assign/telegram/conn-string), fix GIT_WORKFLOW guidance

- BEGIN [A-Z0-9 ]*PRIVATE KEY now covers OPENSSH/RSA/EC variants
- sk- patterns tolerate hyphens and prefixed families (ctx7sk-)
- credential-assign catches PASSWORD=/token:/|API_KEY| tables (placeholder-aware)
- telegram bot tokens + connection strings with embedded passwords
- .obsidian/** third-party plugin code excluded from value scan (noise)
- regression: all 12 files named in REVIEW-FOLLOWUP now flagged
- GIT_WORKFLOW: drop git add . / Windows path, add verifier step,
  note force-push exception for the one-time history rewrite
This commit is contained in:
windyboy
2026-09-26 12:09:11 +08:00
parent be56d86e84
commit f77a4afd50
2 changed files with 55 additions and 22 deletions
+42 -10
View File
@@ -3,14 +3,36 @@
import { execSync } from 'node:child_process'
import { readFileSync } from 'node:fs'
// 值形态的占位符 / 环境引用:不算泄漏
const PLACEHOLDER =
/(\{\{|<[^>]*>|\$\{|process\.env|\benv\[|your[-_]|example|sample|placeholder|changeme|redacted|\bxxx\b|\.\.\.|\[hidden\])/i
// 只报路径与行号,绝不打印匹配到的内容
const KEY_PATTERNS = [
/sk-or-v1-[A-Za-z0-9]{20,}/,
/sk-[A-Za-z0-9]{32,}/,
/AKIA[0-9A-Z]{16}/,
/gh[pousr]_[A-Za-z0-9]{36,}/,
/glpat-[A-Za-z0-9_-]{20,}/,
/BEGIN PRIVATE KEY/,
/xox[baprs]-[A-Za-z0-9-]{10,}/,
// OpenAI 系(sk-or-v1 / sk-proj / sk-svcacct / 裸 sk-),键内允许连字符
['openai-key', /\bsk-[A-Za-z0-9_-]{16,}/, false],
// 第三方 "xxxsk-" 前缀族(如 ctx7sk-…)
['prefixed-key', /\b[A-Za-z0-9]{2,8}sk-[A-Za-z0-9_-]{16,}/, false],
['aws', /\bAKIA[0-9A-Z]{16}\b/, false],
['github-pat', /\bgh[pousr]_[A-Za-z0-9]{20,}/, false],
['gitlab-pat', /\bglpat-[A-Za-z0-9_-]{20,}/, false],
// 覆盖 OPENSSH / RSA / EC / ENCRYPTED 等全部变体
['private-key', /BEGIN [A-Z0-9 ]*PRIVATE KEY/, false],
['slack', /\bxox[baprs]-[A-Za-z0-9-]{10,}/, false],
// 关键字赋值 / 表格单元格:PASSWORD=… / token: … / | API_KEY | …(值须 ≥16 位密钥形态字符)
[
'credential-assign',
/[A-Za-z0-9_-]{0,32}(?:password|passwd|pwd|token|secret|api[_-]?key|apikey|access[_-]?key|secret[_-]?key|bot[_-]?token|private[_-]?key|credential)["']?\s*[:=|]\s*["']?([A-Za-z0-9_+/=~.!@#$%^&*?:-]{16,})/i,
true,
],
// Telegram bot token:<数字id>:AA<hash>
['telegram-bot', /\b\d{8,10}:AA[A-Za-z0-9_-]{30,}/, false],
// 带内嵌口令的连接串 postgres://user:pass@host
[
'conn-string',
/\b(?:postgres(?:ql)?|mysql|redis|mongodb(?:\+srv)?|amqp|smtp|mssql):\/\/[^\s'"@:/]+:[^\s'"@]{4,}@/,
false,
],
]
const OBSIDIAN_HEX_PATTERN = /^[0-9a-f]{64}$/i
@@ -36,12 +58,22 @@ for (const file of trackedFiles) {
}
const lines = content.split('\n')
// .obsidian/** 是第三方插件代码与状态,值形态规则误报极高(minified JS/CSS);
// 密钥载体 data.json 已解除跟踪,这里只保留 64 位 hex 检查
const isObsidian = file.startsWith('.obsidian/')
for (let i = 0; i < lines.length; i++) {
const line = lines[i]
for (const pattern of KEY_PATTERNS) {
if (pattern.test(line)) {
console.error(`KEY LEAK: ${file}:${i + 1}`)
if (!isObsidian) {
for (const [name, pattern, checkValue] of KEY_PATTERNS) {
const m = pattern.exec(line)
if (!m) continue
// 赋值类:值是占位符 / 环境引用时放行
if (checkValue) {
const value = m[1]
if (!value || PLACEHOLDER.test(value)) continue
}
console.error(`KEY LEAK (${name}): ${file}:${i + 1}`)
found = true
}
}