From 64daf3cb0b4801878c7816e6aa168f8dd4c767a0 Mon Sep 17 00:00:00 2001 From: ikmkj Date: Tue, 3 Mar 2026 18:58:03 +0800 Subject: [PATCH] =?UTF-8?q?fix(XSSInterceptor):=20=E5=A2=9E=E5=BC=BAXSS?= =?UTF-8?q?=E6=8B=A6=E6=88=AA=E5=99=A8=E5=AF=B9=E8=AF=B7=E6=B1=82=E5=A4=B4?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改XSS拦截器对请求头的检查逻辑,当检测到XSS攻击时直接拒绝请求并返回400错误响应。新增错误响应写入方法,记录攻击日志。 --- .../interceptor/XSSInterceptor.java | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/interceptor/XSSInterceptor.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/interceptor/XSSInterceptor.java index adc3ffc..4e87599 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/interceptor/XSSInterceptor.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/interceptor/XSSInterceptor.java @@ -2,8 +2,12 @@ package com.test.bijihoudaun.interceptor; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HtmlUtil; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.test.bijihoudaun.common.response.R; +import com.test.bijihoudaun.common.response.ResultCode; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; import org.springframework.web.servlet.HandlerInterceptor; import java.util.Enumeration; @@ -14,12 +18,15 @@ import java.util.Enumeration; * 注意:此拦截器只能过滤 URL 参数和表单数据,无法过滤 @RequestBody 的 JSON 数据 * JSON 数据的 XSS 过滤由 XssStringDeserializer 处理 */ +@Slf4j public class XSSInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - // 过滤请求头 - filterHeaders(request); + // 过滤请求头,发现 XSS 攻击则拒绝请求 + if (!filterHeaders(request, response)) { + return false; + } // 过滤请求参数(URL 参数和表单数据) filterParameters(request); @@ -29,11 +36,12 @@ public class XSSInterceptor implements HandlerInterceptor { /** * 过滤请求头 + * @return true-通过,false-拒绝请求 */ - private void filterHeaders(HttpServletRequest request) { + private boolean filterHeaders(HttpServletRequest request, HttpServletResponse response) throws Exception { Enumeration headerNames = request.getHeaderNames(); if (headerNames == null) { - return; + return true; } while (headerNames.hasMoreElements()) { @@ -41,12 +49,15 @@ public class XSSInterceptor implements HandlerInterceptor { String headerValue = request.getHeader(headerName); if (StrUtil.isNotBlank(headerValue)) { String filteredValue = HtmlUtil.filter(headerValue); - // 注意:请求头无法直接修改,这里只是记录日志 + // 发现 XSS 内容,记录日志并拒绝请求 if (!headerValue.equals(filteredValue)) { - // 发现 XSS 内容,记录日志 + log.warn("检测到XSS攻击,请求头:{},原始值:{}", headerName, headerValue); + writeErrorResponse(response, "检测到恶意内容,请求被拒绝"); + return false; } } } + return true; } /** @@ -65,4 +76,16 @@ public class XSSInterceptor implements HandlerInterceptor { } } } + + /** + * 写入错误响应 + */ + private void writeErrorResponse(HttpServletResponse response, String message) throws Exception { + response.setContentType("application/json;charset=UTF-8"); + response.setStatus(400); + ObjectMapper mapper = new ObjectMapper(); + response.getWriter().write(mapper.writeValueAsString( + R.fail(ResultCode.FAILED.getCode(), message) + )); + } }