Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions scripts/unit-smoke.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,29 @@ t('敏感不命中:.gitignore、README.md、src/main.go', () => {
assert.equal(isSensitivePath('README.md'), false);
assert.equal(isSensitivePath('src/main.go'), false);
});
// issue #11 回归:凭据词内嵌于源码文件名(src/key.js、cert.ts 等)不得误判为敏感文件
// ——噪声稀释真正凭据命中信号(旧正则 (.*\.)? 可跳过,key 后跟 .js 的点即命中)。
t('敏感不命中:凭据词内嵌于源码文件名(issue #11 回归)', () => {
assert.equal(isSensitivePath('src/key.js'), false);
assert.equal(isSensitivePath('src/key.ts'), false);
assert.equal(isSensitivePath('src/cert.js'), false);
assert.equal(isSensitivePath('src/cert.ts'), false);
assert.equal(isSensitivePath('src/pem.js'), false);
assert.equal(isSensitivePath('sessionkey.go'), false);
assert.equal(isSensitivePath('keycmd.go'), false);
});
// issue #11 回归:凭据词作为独立扩展名仍须命中(修复不得造成真凭据漏报。
// id_rsa/credentials.json/.env 由各自独立规则覆盖,一并钉住防回归)。
t('敏感命中:凭据词为独立扩展名(issue #11 保留行为)', () => {
assert.equal(isSensitivePath('my.key'), true);
assert.equal(isSensitivePath('key.pem'), true);
assert.equal(isSensitivePath('cert.pfx'), true);
assert.equal(isSensitivePath('certs/app.pem'), true);
assert.equal(isSensitivePath('my.key.bak'), true);
assert.equal(isSensitivePath('id_rsa'), true);
assert.equal(isSensitivePath('credentials.json'), true);
assert.equal(isSensitivePath('.env'), true);
});
t('listSensitiveFiles 混合清单只点名命中项', () => {
const hits = listSensitiveFiles(['README.md', '.env', 'src/main.go', '.ssh/id_ed25519']);
assert.deepEqual(hits.map((h) => h.path).sort(), ['.env', '.ssh/id_ed25519'].sort());
Expand Down
9 changes: 8 additions & 1 deletion src/sensitive-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@ export const SENSITIVE_PATH_PATTERNS = [
/(^|\/)\.[^/]*key[^/]*$/i,
/(^|\/)\.[^/]*secret/i,
/(^|\/)\.env(\.[^/]+)?$/i, // .env / .env.production 等
/(^|\/)(.*\.)?(pem|p12|pfx|keystore|jks|cert|crt|key|kdbx|otpkey)(\.|$)/i,
// 凭据扩展名必须作为「独立扩展名」出现(my.key、cert.pfx、server.crt.bak 等):
// 敏感词前必须由点号分隔([^/]*\.),后跟行尾或再一个点(如 .key.bak 的 .bak)。
// 旧正则的 (.*\.)? 可整体不参与匹配,导致 key.js / cert.ts / pem.js 中敏感词
// 后跟源码扩展名的点即满足 (\.|$)——src/key.js、src/key.ts 等合法源码被误判为
// 敏感文件,噪声稀释真正凭据命中的信号(issue #11)。修后路径段内嵌的
// key/cert/pem(sessionkey.go、keycmd.go 等)也不再命中;id_rsa/credentials/.env
// 等由各自独立规则覆盖,不受此行影响。
/(^|\/)[^/]*\.(pem|p12|pfx|keystore|jks|cert|crt|key|kdbx|otpkey)(\.|$)/i,
/(^|\/)credentials[^/]*$/i,
// token 模式收紧(形态:独立词段 token(s) + **凭据类扩展名或路径结尾**)——
// 原 `.*token[^/]*$` 命中路径任意位置含 "token" 的文件(src/tokenizer.js、
Expand Down
Loading