bookworm-smart-assistant/scripts/sanitize.js

60 lines
2.4 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
/**
* 共享日志脱敏模块 (v5.9)
*
* 统一所有组件的敏感信息过滤规则避免规则分散导致不一致
* route-interceptor.js activity-logger.js 共同引用
*/
/**
* 日志脱敏: 移除疑似敏感信息
* @param {string} text - 原始文本
* @returns {string} 脱敏后文本
*/
function sanitize(text) {
if (!text || typeof text !== 'string') return text || '';
return text
// 键值对形式: key=xxx, token: xxx, password=xxx 等
.replace(/(?:key|token|password|secret|credential|apikey|api_key|auth|passwd)[\s]*[=:]\s*\S{6,}/gi, (m) => {
const sep = m.indexOf('=') !== -1 ? '=' : ':';
const prefix = m.slice(0, m.indexOf(sep) + 1);
return prefix + ' [REDACTED]';
})
// 已知 token 前缀: sk-, ghp_, Bearer 等 (后跟 >=10 字符)
.replace(/\b(?:sk-|ghp_|gho_|github_pat_|xoxb-|xoxp-|Bearer\s+)\S{10,}/g, '[REDACTED_TOKEN]')
// AWS Access Key (AKIA 开头 20 字符)
.replace(/\bAKIA[A-Z0-9]{16}\b/g, '[REDACTED_TOKEN]')
// JWT token (eyJ 开头的 Base64url 段)
.replace(/\beyJ[A-Za-z0-9_-]{20,}(?:\.[A-Za-z0-9_-]+)*/g, '[REDACTED_TOKEN]')
// 疑似 Base64 编码密钥 (长度 >= 40)
.replace(/\b[A-Za-z0-9+/]{64,}={0,2}\b/g, (m) => { // V07 修复: 阈值 40→64减少 Git SHA/路径误杀
if (/^[A-Za-z0-9+/]+={0,2}$/.test(m)) return '[REDACTED_B64]';
return m;
})
// UUID 格式 Token (当作为 TOKEN/KEY/SECRET 等的值出现时)
.replace(/(?:TOKEN|KEY|SECRET|CREDENTIAL|PASSWORD|API_KEY)[\s]*[=:]\s*[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, (m) => {
const sep = m.indexOf('=') !== -1 ? '=' : ':';
const prefix = m.slice(0, m.indexOf(sep) + 1);
return prefix + ' [REDACTED_UUID]';
});
}
if (typeof module !== 'undefined') {
// #12: 磁盘满降级日志 — appendFileSync 失败时 fallback 到 stderr
function safeAppendLog(filePath, jsonData) {
try {
const dir = require('path').dirname(filePath);
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
fs.appendFileSync(filePath, JSON.stringify(jsonData) + '\n');
} catch (e) {
// 磁盘满或权限错误时输出到 stderr (至少留下审计痕迹)
try { process.stderr.write('[LOG-FALLBACK] ' + JSON.stringify(jsonData) + '\n'); } catch {}
}
}
module.exports = {
safeAppendLog, sanitize };
}