当前在处理系统安全测试缺陷问题时,发现诸多安全问题,记录解决过程和方法,分享共勉。
解释:
CSRF不懂看我历史文章:CSRF
主机头攻击:
在计算机网络中,主机头攻击是一种网络安全攻击方式,它利用了网络协议栈中的缺陷,以伪造的IP地址为源地址向网络发送数据包,目的是在欺骗目标主机,使其认为这些数据包是从指定的合法源发出的,并从而欺骗目标主机执行一些攻击者预期的动作。
主机头攻击通常也被称作IP欺骗(IP Spoofing),攻击者会伪造数据包中的源IP地址,使其看起来像是从合法的主机上发出的,这样就可以避开目标主机的IP地址过滤和安全验证机制,欺骗目标主机执行攻击者的恶意操作,例如进行DDoS攻击等。由于源地址伪造,攻击者通常很难被追踪和识别,所以主机头攻击被广泛应用于各种恶意网络攻击中。
简单讲就是伪造请求地址(请求头中的host)
限制请求方式:
在某些系统安全测试过程中只允许使用GET或POST方法,使用其他的HTTP协议方法可能会导致系统出现异常或崩溃,从而影响测试的结果。而使用GET和POST方法则可以最大程度地保证测试的稳定性和可靠性。
当然最先想到的可以用NGINX处理,让NGINX帮我们代理拦截,主机头攻击用NGINX也可以 。
但是这里尽量花最小钱办最大事,一个拦截器处理。上代码
package com.iot.framework.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Base64;
/**
* CSRF - Referer 拦截器
*
* @author jiangfy
*/
@Component
public class RefererInterceptor extends HandlerInterceptorAdapter {
/**
* 白名单
*/
private String[] refererDomain = new String[]{"asaGsd4MDkxLw==", "aHR0cDovLzIyLjE4MTo4MDkxLw==", "aHR0cDovLzEwL1BnL2luZGV4Lmh0bWw=", "aHR0cDovLsfdsfDo4MDkxLw=="};
private String[] hostDomain = new String[]{"bG9jYWxob3sfddN0OjE1fdfsMTA1"};
/**
* 是否开启referer校验
*/
private Boolean checkReferer = true;
/**
* 是否开启GET / POST校验
*/
private Boolean checkReqType = true;
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
if (checkReqType) {
String method = req.getMethod();
// 验证非get post请求
if (!"GET".equals(method) && !"POST".equals(method)) {
// 禁止非GET和POST请求访问
resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
resp.getWriter().write("禁止非GET或POST请求访问!");
return false;
}
}
if (!checkReferer) {
return true;
}
//referer 代表请目标地址
String referer = req.getHeader("Referer");
//host 代表请请求地址 请求地址不可变
String host = req.getHeader("Host");
String refererEncryUrl;
String hostEncryUrl;
boolean r = false;
boolean h = false;
if (referer == null || host == null) {
// 状态置为404
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
return false;
}
// 判断referer域名是否在白名单中
if (refererDomain != null) {
refererEncryUrl = Base64.getEncoder().encodeToString(referer.getBytes());
for (String rfr : refererDomain) {
if (rfr.equals(String.valueOf(refererEncryUrl))) {
r = true;
}
}
}
// 判断host请求地址是否在白名单中
if (hostDomain != null) {
hostEncryUrl = Base64.getEncoder().encodeToString(host.getBytes());
for (String hs : hostDomain) {
if (hs.equals(String.valueOf(hostEncryUrl))) {
h = true;
}
}
}
return r == true && h == true;
}
}
定义 “referer白名单” 和 “host白名单”,拦截非GET或POST请求。比对请求中的referer和host值与白名单,只有同时符合才允许通过。
注册拦截器
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired
private RefererInterceptor refererInterceptor;
/**
* 注册过滤器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(refererInterceptor).addPathPatterns("/**").excludePathPatterns("/", "/login", "/logout");
}
}