跨站点请求伪造
在项目进行渗透测试的时候,测试出了系统漏洞:
跨站点请求伪造-CSRF(Cross Site Request Forgery):是一种网络攻击方式。
通常的解决方法有以下几种:
- 验证Referer
- 在请求参数中添加token验证
- 在HTTP头中自定义属性并验证
这里我们只讨论第一种,验证Referer,如需其他,可参考:www.cnblogs.com/xlyslr/p/57…
示例代码
这里我使用的Spring Cloud Gateway,其他网关可参考实现:
@Slf4j
@Component
public class RefererFilter implements GlobalFilter, Ordered {
@Value("${cmp.referer}")
private String referer;
private static final String REFERER = "referer";
@Override
public int getOrder() {
return 0;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
HttpHeaders headers = request.getHeaders();
String headerReferer = headers.getFirst(REFERER);
ServerHttpResponse response = exchange.getResponse();
log.info("function=RefererFilter,headerReferer = {}", headerReferer);
boolean contain = false;
String[] referers = referer.split(",");
for (String referer : referers) {
if (StringUtils.hasText(headerReferer) && headerReferer.startsWith(referer)) {
contain = true;
break;
}
}
if (StringUtils.isEmpty(headerReferer) || !contain) {
log.error("referer请求头为空!,请求路径为: {}", request.getPath().toString());
response.setStatusCode(HttpStatus.PRECONDITION_FAILED);
return errorInfo(exchange, "referer请求头为空!");
}
return chain.filter(exchange);
}
/**
* 返回response
*
* @param exchange exchange
* @param message 异常信息
*/
public static Mono<Void> errorInfo(ServerWebExchange exchange, String message) {
Map<String, Object> resultMap = new HashMap<>(5);
resultMap.put("message", message);
resultMap.put("code", -1);
return Mono.defer(() -> {
byte[] bytes = new byte[0];
try {
bytes = new ObjectMapper().writeValueAsBytes(resultMap);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
DataBuffer buffer = response.bufferFactory().wrap(bytes);
return response.writeWith(Flux.just(buffer));
});
}
}
复制代码
配置文件:
cmp:
referer: http://localhost,http://127.0.0.1,https://...
复制代码
最终效果
如果请求头上没有携带Referer,就返回错误信息。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END