渗透测试漏洞修复

This commit is contained in:
马三炮 2025-11-26 15:16:39 +08:00
parent 819512ea6c
commit 388012656c
4 changed files with 116 additions and 4 deletions

View File

@ -65,7 +65,7 @@ public class TokenService
redisService.deleteObject(oldTokenKey); redisService.deleteObject(oldTokenKey);
} }
// 存储新的token关联 // 存储新的token关联
redisService.setCacheObject(userTokenKey, token, expireTime, TimeUnit.SECONDS); redisService.setCacheObject(userTokenKey, token, expireTime, TimeUnit.MINUTES);
String userKey = getTokenKey(loginUser.getToken()); String userKey = getTokenKey(loginUser.getToken());
// Jwt存储信息 // Jwt存储信息
Map<String, Object> claimsMap = new HashMap<String, Object>(); Map<String, Object> claimsMap = new HashMap<String, Object>();

View File

@ -0,0 +1,50 @@
package com.bonus.gateway.config;
/**
* @author 马三炮
* @date 2025/11/26
*/
import org.apache.commons.lang3.StringEscapeUtils;
/**
* XSS过滤工具类
*/
public class XssFilterUtil {
/**
* 过滤特殊字符黑名单方式
*/
public static String filterSpecialChars(String input) {
if (input == null || input.isEmpty()) {
return input;
}
// 替换需过滤的字符可根据需求调整替换策略清空或转义
return input.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll("\"", "&quot;")
.replaceAll("'", "&#39;")
.replaceAll("%", "&#37;")
.replaceAll(";", "&#59;")
.replaceAll("\\(", "&#40;")
.replaceAll("\\)", "&#41;")
.replaceAll("\\+", "&#43;");
}
/**
* HTML转义推荐优先使用
* 基于Apache Commons Text工具类更全面的转义
*/
public static String htmlEscape(String input) {
return StringEscapeUtils.escapeHtml4(input);
}
/**
* 组合过滤先黑名单过滤再HTML转义
*/
public static String xssFilter(String input) {
String filtered = filterSpecialChars(input);
return htmlEscape(filtered);
}
}

View File

@ -0,0 +1,51 @@
package com.bonus.gateway.config;
/**
* @author 马三炮
* @date 2025/11/26
*/
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Map;
public class XssRequestWrapper extends HttpServletRequestWrapper {
public XssRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
return XssFilterUtil.xssFilter(value);
}
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values == null) {
return null;
}
for (int i = 0; i < values.length; i++) {
values[i] = XssFilterUtil.xssFilter(values[i]);
}
return values;
}
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> map = super.getParameterMap();
map.forEach((key, values) -> {
for (int i = 0; i < values.length; i++) {
values[i] = XssFilterUtil.xssFilter(values[i]);
}
});
return map;
}
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
return XssFilterUtil.xssFilter(value);
}
}

View File

@ -2,8 +2,10 @@ package com.bonus.gateway.filter;
import com.bonus.common.core.utils.StringUtils; import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.utils.html.EscapeUtil; import com.bonus.common.core.utils.html.EscapeUtil;
import com.bonus.gateway.config.XssFilterUtil;
import com.bonus.gateway.config.properties.XssProperties; import com.bonus.gateway.config.properties.XssProperties;
import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufAllocator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GatewayFilterChain;
@ -20,6 +22,8 @@ import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
/** /**
@ -27,6 +31,7 @@ import java.nio.charset.StandardCharsets;
* *
* @author zys * @author zys
*/ */
@Slf4j
@Component @Component
@ConditionalOnProperty(value = "security.xss.enabled", havingValue = "true") @ConditionalOnProperty(value = "security.xss.enabled", havingValue = "true")
public class XssFilter implements GlobalFilter, Ordered public class XssFilter implements GlobalFilter, Ordered
@ -46,10 +51,10 @@ public class XssFilter implements GlobalFilter, Ordered
return chain.filter(exchange); return chain.filter(exchange);
} }
// 非json类型不过滤 // 非json类型不过滤
if (!isJsonRequest(exchange)) /*if (!isJsonRequest(exchange))
{ {
return chain.filter(exchange); return chain.filter(exchange);
} }*/
// excludeUrls 不过滤 // excludeUrls 不过滤
String url = request.getURI().getPath(); String url = request.getURI().getPath();
if (StringUtils.matches(url, xss.getExcludeUrls())) if (StringUtils.matches(url, xss.getExcludeUrls()))
@ -76,8 +81,14 @@ public class XssFilter implements GlobalFilter, Ordered
join.read(content); join.read(content);
DataBufferUtils.release(join); DataBufferUtils.release(join);
String bodyStr = new String(content, StandardCharsets.UTF_8); String bodyStr = new String(content, StandardCharsets.UTF_8);
try {
bodyStr = java.net.URLDecoder.decode(bodyStr, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
// 防xss攻击过滤 // 防xss攻击过滤
bodyStr = EscapeUtil.clean(bodyStr); bodyStr = EscapeUtil.clean(bodyStr);
bodyStr = XssFilterUtil.filterSpecialChars(bodyStr);
// 转成字节 // 转成字节
byte[] bytes = bodyStr.getBytes(); byte[] bytes = bodyStr.getBytes();
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT); NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
@ -104,7 +115,7 @@ public class XssFilter implements GlobalFilter, Ordered
/** /**
* 是否是Json请求 * 是否是Json请求
* *
* @param exchange HTTP请求 * @param exchange HTTP请求
*/ */
public boolean isJsonRequest(ServerWebExchange exchange) public boolean isJsonRequest(ServerWebExchange exchange)