【Java】-CSRF漏洞问题
·
1、什么是CSRF漏洞?
CSRF(跨站请求伪造)攻击确实可被用于篡改账户信息、执行转账操作或修改敏感配置,其核心原理是攻击者诱导用户浏览器在用户不知情的情况下,向目标网站发送携带用户身份验证信息(如Cookie)的恶意请求。为有效防范此类攻击,可从技术防护、用户操作规范、系统架构优化三个层面进行针对性修改与加固。
2、解决措施:验证HTTP Referer字段
- 说明:该措施是众多解决措施一种,我的项目适用,本文仅作记录。
- 原理:检查请求的Referer头,确保请求来自合法来源。
- 实施方式:
- 服务端验证Referer头是否以目标网站域名开头,若来自其他域名则拒绝请求
3、项目配置措施
1)寻找安全配置类,继承自 WebSecurityConfigurerAdapter 的类
2)在 configure(HttpSecurity http) 方法中添加referer校验逻辑:
.addFilterBefore(new RefererValidationFilter(), UsernamePasswordAuthenticationFilter.class)
【说明】
UsernamePasswordAuthenticationFilter导入的包:import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable()
.addFilterBefore(new RefererValidationFilter(), UsernamePasswordAuthenticationFilter.class);
}
RefererValidationFilter类如下:
package ..............;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
@Slf4j
public class RefererValidationFilter extends OncePerRequestFilter {
// 允许的域名列表
private List<String> allowedDomains = Arrays.asList(
"localhost",
"127.0.0.1"
);
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String referer = request.getHeader("Referer");
log.info("校验referer: {}", referer);
// 对于敏感请求方法进行referer校验
if (isSensitiveMethod(request.getMethod()) && !isValidReferer(referer)) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.getWriter().write("Invalid referer");
return;
}
filterChain.doFilter(request, response);
}
private boolean isSensitiveMethod(String method) {
// 对POST、PUT、DELETE等敏感操作进行校验
return "POST".equals(method) || "PUT".equals(method) || "GET".equals(method) ||
"DELETE".equals(method) || "PATCH".equals(method);
}
private boolean isValidReferer(String referer) {
if (referer == null || referer.isEmpty()) {
return false;
}
try {
String refererHost = new java.net.URL(referer).getHost();
return allowedDomains.stream().anyMatch(domain ->
refererHost.equals(domain) || refererHost.endsWith("." + domain)
);
} catch (Exception e) {
return false;
}
}
}
更多推荐

所有评论(0)