缓存里能不能放密码、身份证这些敏感数据?
很多人做开发时图省事,顺手就把用户的登录凭证、身份证号甚至银行卡信息塞进了Redis或者浏览器的localStorage里。反正用起来快,下次访问直接从缓存拿,不用再查数据库。但这样做其实挺危险的。
缓存的本质是临时存储
不管是服务器端的Redis、Memcached,还是前端的sessionStorage,缓存的设计初衷是为了提升性能,不是为了安全存储。它可能被其他进程访问,也可能因为配置不当暴露到公网。比如一个Redis实例没设密码,又被绑定了公网IP,那里面的数据等于直接摆在外面。
曾经有家公司把用户会话token存在Redis里,结果Redis没做访问控制,黑客连上去一扫,成千上万的活跃token全拿走了,相当于直接“登”进了所有用户账号。
浏览器缓存更不靠谱
有人喜欢把用户信息存localStorage,方便页面刷新后保持登录状态。可只要网站有任何一个XSS漏洞,攻击者一段脚本就能把整个localStorage读走。你存了手机号、姓名,人家分分钟拿到手。
更别说用户自己用的设备也不一定安全。公共电脑上登了个账号,关掉浏览器没清缓存,下一个人打开页面,信息还在。
真要缓存,得先脱敏
如果业务确实需要缓存一些关联数据,比如根据用户ID查权限,可以缓存处理后的结果,但别放原始敏感字段。例如:
{
"userId": "u10086",
"role": "admin",
"permissions": ["edit", "delete"]
}这种可以缓存,但像下面这种就别碰了:
{
"userId": "u10086",
"name": "张三",
"idCard": "110101199001011234",
"phone": "13800138000"
}加密也不能完全放心
有人说,我加密存总行了吧?比如用AES把身份证号加密后再放进缓存。听起来靠谱,实际问题也不少。密钥怎么管理?放在代码里?配置文件里?一旦泄露,加密形同虚设。而且加解密增加延迟,违背了缓存“提速”的本意。
更现实的做法是:敏感信息只在内存中短暂存在,用完即删。数据库查出来,处理完逻辑,立刻释放引用,不要往缓存里搬。
正确使用缓存的方式
把缓存当成“可丢弃”的中间层。系统设计时就要假设:任何缓存都可能被清空、被读取、被篡改。所以:
- 认证token用短期有效的JWT,避免长期有效
- 用户资料类数据,优先从服务端接口实时拉取,配合合理过期策略
- 缓存键设计避免包含敏感信息,比如别用身份证当key
说白了,缓存是用来优化体验的,不是保险柜。该守的底线不能因为“方便”就让步。