Hello,这里是爱 Coding,爱 Hiphop,爱喝点小酒的 AKA 柏炎。
我们部门每次大版本发布,都需要走一道公司的安全测试。
这不最近公司的安全测试标准提高了,我所负责的用户服务被一口气提了10个安全问题。
好家伙,3.25没跑了。
不过用户中心是核心的底层业务服务,它的数据安全性与系统稳定性都是极其重要的,发现了Bug,我们只能逐个去修复了。
本文将针对其中比较典型三个问题做分析与解决方案阐述。
一、IP伪造
日常业务开发的过程中,我们可能会需要获取请求接口的用户IP信息。
为了防止黑客通过爆破的方式登陆系统,我将记录每一次用户登陆的IP,在一定时间范围内连续输入错误的用户名或者密码,将锁定IP。此IP在锁定时间内无法再请求登陆接口。
修复前获取IP逻辑
static String getIpAddr(HttpServletRequest request) {
if (request == null) {
return "unknown";
}
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
return "0:0:0:0:0:0:0:1".equals(ip) ? LOCAL_IP : ip;
}
复制代码
从业务功能使用的角度上来看,这段代码没有任何问题,我们能够从HttpServletRequest中获取到报文中的IP数据。
但是发现没有,我们获取的IP数据都是从请求头中获取的,而请求头的所有报文信息都是可以通过报文进行伪造的。只要攻击的黑客弄一个IP池,不断的变化,我们的防爆破机制就失效了。
解决思路
说实话,我当时为了完成这个IP获取需求,上面的代码也是直接百度了一份,发现能用也就用了。
我并不知道Header中获取到的IP值的意思是什么(文中不阐述比如ÿ