问题出现得很突然,日志倒是留得挺全。日志脱敏脚本用 \d{16,19} 匹配银行卡,上线后发现带空格分组的 6222 0202 0000 1234 仍然明文,还有带横杠的写法也漏了。

刚开始盯着「日志写在前置网关,脱敏脚本在应用侧」,折腾了半个多小时,排掉了。

原因不止一个,得分开看。正则只匹配连续数字,没考虑空格与横杠分组。也可能是匹配到之后替换函数只处理了第一个分组。

另外,多行日志被合并处理,跨行数字被截断。

动手时先用样本验证现有正则的命中情况

python -c "import re;print(re.findall(r'\\d{16,19}','6222 0202 0000 1234'))"

然后改成允许分隔符的写法并保留后四位

python -c "import re;print(re.sub(r'\\b(\\d[\\d -]{14,25}\\d)\\b',lambda m:m.group(1)[:6]+'********'+m.group(1)[-4:],'6222 0202 0000 1234'))"

再往下把脱敏下沉到日志采集侧统一处理

python mask_agent.py --patterns card.txt --apply

等前面都确认过,再用历史日志回放验证漏网数量

python replay_mask.py --log old.log --report miss.txt

别只看报错消失,验证要多做一步。带空格与横杠的卡号都被替换成掩码,回放历史日志后命中数量为零,掩码保留前六后四可人工核对。

脱敏规则的难点在格式变体而不是位数,先收集真实样本再写正则,放在采集侧比放在业务代码里更难绕过。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189