敏感信息泄露漏洞修复建议
去年某电商平台被拖库,敏感起因是信息泄露修复一个测试接口没下线,返回包里直接带了用户手机号和收货地址。漏洞攻击者没用什么高深手法,建议就是敏感拿 Burp Suite 跑了一遍目录,发现了 /api/v1/debug/user。信息泄露修复这个接口连鉴权都没有。漏洞修复过程不到两小时,建议但数据已经在外网飘了三天。敏感
这类漏洞的信息泄露修复根源往往不是技术难度,而是漏洞开发、运维、建议安全三方之间的敏感信息差。开发觉得测试接口上线前会删,信息泄露修复运维觉得安全组会拦,漏洞安全团队觉得开发会做鉴权。结果谁都没做。
修复敏感信息泄露,第一件事是搞清楚“敏感”的边界。不是只有密码和身份证号算敏感。手机号、邮箱、设备指纹、地理位置、订单号、甚至用户 ID 的递增规律,组合起来就能拼出完整画像。我见过一个案例,某 App 的分享链接里带了 user_id 的 base64 编码,解码后是纯数字,遍历一遍就能拿到全站用户昵称和头像。这算不算敏感?从合规角度可能不算,从攻击链角度它就是入口。
接口层面的修复优先级最高。所有返回用户数据的接口,必须过一遍鉴权中间件。别信前端传的 user_id,从 session 或 token 里取。有个团队用 JWT 存了用户角色,但接口只验签名不验角色,普通用户改个 role 字段就能查别人订单。修复方案很简单:在网关层加一道校验,把 token 里的 sub 和请求参数里的 user_id 做比对,不一致直接 403。代码量不到二十行,但能挡住八成越权查询。
日志和错误信息是另一个重灾区。生产环境返回堆栈信息,等于把数据库表名、字段名、甚至 SQL 语句直接送给攻击者。我习惯在 Nginx 层加一条规则:任何 5xx 响应,body 只返回 { "error": "internal"},详细堆栈写进本地日志。这样既不影响排查,也不对外暴露结构。还有 X-Powered-By、Server 这些响应头,能删就删。攻击者看到 Express 就知道去试 Node.js 的常见漏洞,看到 PHP/7.2 就去翻对应版本的 CVE。信息给得越少,攻击成本越高。
前端代码里的泄露经常被忽略。打包后的 JS 文件里藏着注释掉的 API key、内网地址、甚至测试账号密码。有个项目用 webpack 打包,process.env 里的变量没过滤,直接打进了 bundle。攻击者下载 main.js,搜索 api_key 就拿到了高德地图的 key。修复方式是在 CI 阶段加一步:用正则扫打包产物,匹配 key|secret|token|password 等关键词,命中就阻断发布。工具用 trufflehog 或自己写脚本都行,关键是卡住流水线。
数据库层面,别把敏感字段明文存。手机号、邮箱做加密或哈希,需要展示时再解密。查询接口用视图或存储过程,限制直接 SELECT *。我见过一个后台管理系统,列表页直接把 user 表所有字段返给前端,包括 password_hash 和 salt。虽然哈希算法是 bcrypt,但攻击者拿到后可以离线爆破弱密码。修复方案是后端做字段白名单,只返回 id、nickname、avatar 三个字段。简单粗暴,但有效。
最后说监控。敏感信息泄露往往没有明显异常流量,一个接口被遍历几千次,在访问日志里就是一堆 200。可以针对返回体大小做基线告警:正常用户信息接口返回 500 字节,突然出现大量 2KB 的响应,大概率是有人加了 ?debug=1 或改了 fields 参数。再配合 IP 维度限频,单 IP 每分钟超过 100 次查询就封禁十分钟。这些策略不复杂,但能把攻击窗口从几天压缩到几分钟。
修复不是一次性的。每次发版前跑一遍自动化扫描,用 nuclei 或 gitleaks 过一遍代码和接口。发现泄露先止血——下线接口、轮换密钥、封禁 IP——再定位根因。别一上来就改代码,攻击者不会等你。