概述
大多数团队都有 maskEmail 之类的函数。泄漏几乎不出在函数本身,而出在新的导出路径没调用它、调试日志打印了整行、测试数据里提交了真实客户信息。只测试辅助函数会带来虚假的安全感,应测试输出:每一个离开可信边界的文件、日志行与接口响应。
步骤
- 定义输出格式明确的脱敏函数:
export const maskEmail = (email) => email.replace(/^([^@]).*?(@.*)$/, '$1***$2');
export const maskCard = (pan) => `**** **** **** ${pan.slice(-4)}`;
- 用属性测试断言不变量:域名保留、原文不再出现。
- 对每个真实输出路径做断言,而不是只测函数:
const row = buildExportRow({ email: '[email protected]', pan: '4242424242424242' });
assert.ok(!JSON.stringify(row).includes('[email protected]'));
- 导出改为白名单:只有显式允许并脱敏的字段才会输出,新字段默认不出现。
- 在 CI 中扫描测试数据与黄金文件中的卡号样式数字。
验证
导出结果中邮箱应为 a***@example.com,卡号应为 **** **** **** 4242,序列化后的整行不包含原始值。新增一个未登记的 ssn 字段后,导出结果不应包含该字段。扫描命令只应命中已登记的测试卡号。
注意事项
- 脱敏降低暴露面但不等于匿名化,聚合数据仍可能重新识别个人。
- 格式保留的脱敏在密钥或方案较弱时可逆,不能替代加密。
- 支持人员需要定位客户时,应使用带密钥的哈希做关联,而不是放宽脱敏规则。
- 测试只覆盖已执行的路径,新增导出任务仍可能绕过辅助函数。
- 日志、分析事件、错误上报、数据库导出都是数据出口,需要逐一覆盖。