客服导出的用户 CSV 第 9 列是 bcrypt 哈希,文件被转发到二十多人的群里,安全扫描在共享盘里发现了这批数据。日志里能对上时间点,这种反而好排。

查询写的是 SELECT *,导出层只按字段名排除了几个已知列。后来表里新增的 password_hash 和 salt 自动进入结果集,没有任何拦截。这一点先确认清楚,后面就不用反复试。

SELECT id, nickname, phone, created_at FROM users;
-- 不要 SELECT *,password_hash 不进入导出 DTO

围绕「导出敏感字段」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。

报错里带路径的,先去看那个路径在不在、权限对不对。同一份配置存在多处的,先确认改的是被加载的那一份。

处理上按这个顺序:导出改用字段白名单 只挑明确需要的列;查询和导出各建一个 DTO 不要让实体直接透出;上线前扫一遍导出接口的返回列 与敏感字段清单比对。

结果对不对很好判断,再导出同一批用户,列数固定为 4 列,password_hash 和 salt 都不在文件里,扫描工具不再告警。

作者 9823189