Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
0791df7b71
|
|
@ -68,11 +68,9 @@ public class ParamSecureHandler implements AsyncHandlerInterceptor {
|
|||
// 过滤文件上传功能-只对参数进行校验
|
||||
if (isFileUpload(request)) {
|
||||
String params = request.getParameter("params");
|
||||
// boolean flag = XssCheck.xssCleanNew(params);
|
||||
XssCheck.XssCheckResult xssCheckResult = XssCheck.xssCheckWithResult(null, params, null, null);
|
||||
if(!xssCheckResult.isSafe()){
|
||||
Map<String, Object> map = new HashMap<>(16);
|
||||
// returnJson(response, "输入值非法", 500,null);
|
||||
List<XssCheck.IllegalParameter> illegalParameters = xssCheckResult.getIllegalParameters();
|
||||
if(CollectionUtils.isNotEmpty(illegalParameters)){
|
||||
log.error("非法参数{}",illegalParameters);
|
||||
|
|
@ -87,19 +85,15 @@ public class ParamSecureHandler implements AsyncHandlerInterceptor {
|
|||
}
|
||||
XssRequestWrapper requestWrapper = new XssRequestWrapper(request);
|
||||
|
||||
// System.err.println(JSON.toJSONString(request.getParameterMap()));
|
||||
/**
|
||||
* 校验参数是否合法
|
||||
*/
|
||||
if (!requestWrapper.isChecked()) {
|
||||
/*log.error("输入值非法: queryString={}, body={}",
|
||||
StringUtils.defaultString(requestWrapper.getQueryString(), "null"),
|
||||
StringUtils.defaultString(requestWrapper.getReaderParam(), "null"));*/
|
||||
|
||||
Map<String, Object> map = new HashMap<>(16);
|
||||
List<XssRequestWrapper.IllegalParameter> illegalParameters = requestWrapper.getIllegalParameters();
|
||||
if(CollectionUtils.isNotEmpty(illegalParameters)){
|
||||
log.error("非法参数{}",illegalParameters);
|
||||
// log.error("非法参数{}",illegalParameters);
|
||||
XssRequestWrapper.IllegalParameter illegalParameter = illegalParameters.get(0);
|
||||
map.put("paramName",illegalParameter.getParamName().replace("REQUEST_BODY.",""));
|
||||
map.put("originalValue",illegalParameter.getOriginalValue());
|
||||
|
|
@ -108,7 +102,6 @@ public class ParamSecureHandler implements AsyncHandlerInterceptor {
|
|||
returnJson(response, "输入值非法", 500,map);
|
||||
return false;
|
||||
}
|
||||
// System.err.println(JSON.toJSONString(request.getParameterMap()));
|
||||
|
||||
/**
|
||||
* 获取所有跳转路径参数,保留传入下个界面
|
||||
|
|
@ -123,7 +116,7 @@ public class ParamSecureHandler implements AsyncHandlerInterceptor {
|
|||
/**
|
||||
* 检查数据流参数
|
||||
*/
|
||||
String readerParam = requestWrapper.getReaderParam();
|
||||
/*String readerParam = requestWrapper.getReaderParam();
|
||||
// 判断是否是文件上传,是不对流参数进行验证
|
||||
String uplFile = "/upload", upImage = "/uploadFiles",path="/";
|
||||
if (!requestUrl.contains(uplFile) && !requestUrl.contains(upImage) && !requestUrl.contains(path)) {
|
||||
|
|
@ -132,7 +125,7 @@ public class ParamSecureHandler implements AsyncHandlerInterceptor {
|
|||
returnJson(response, "不安全参数", 500,null);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,23 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
|
|||
// 预编译所有正则表达式模式以提高性能
|
||||
private static final List<Pattern> XSS_PATTERNS = new ArrayList<>();
|
||||
|
||||
// 需要忽略特殊字符校验的URL路径
|
||||
private static final Set<String> IGNORE_SPECIAL_CHARS_URLS = new HashSet<>();
|
||||
|
||||
// 需要忽略的特殊字符模式(在修改密码时需要忽略的)
|
||||
private static final List<Pattern> IGNORE_SPECIAL_PATTERNS = new ArrayList<>();
|
||||
|
||||
static {
|
||||
// 初始化忽略校验的URL路径
|
||||
IGNORE_SPECIAL_CHARS_URLS.add("/smartArchives/system/user/resetPwd");
|
||||
IGNORE_SPECIAL_CHARS_URLS.add("/smartArchives/system/user/profile/updatePwd");
|
||||
// 可以根据需要添加更多修改密码的URL
|
||||
|
||||
// 初始化需要忽略的特殊字符模式
|
||||
IGNORE_SPECIAL_PATTERNS.add(Pattern.compile("@.*", Pattern.CASE_INSENSITIVE)); // @符号
|
||||
IGNORE_SPECIAL_PATTERNS.add(Pattern.compile("!.*", Pattern.CASE_INSENSITIVE)); // 感叹号
|
||||
IGNORE_SPECIAL_PATTERNS.add(Pattern.compile("%", Pattern.CASE_INSENSITIVE)); // %
|
||||
|
||||
// 初始化所有XSS模式
|
||||
XSS_PATTERNS.add(Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE));
|
||||
XSS_PATTERNS.add(Pattern.compile("src[\r\n]*=[\r\n]*'(.*?)'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL));
|
||||
|
|
@ -73,10 +89,7 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
|
|||
XSS_PATTERNS.add(Pattern.compile("%5b", Pattern.CASE_INSENSITIVE)); // [ 的URL编码
|
||||
XSS_PATTERNS.add(Pattern.compile("%5d", Pattern.CASE_INSENSITIVE)); // ] 的URL编码
|
||||
|
||||
// 其他特殊字符
|
||||
XSS_PATTERNS.add(Pattern.compile("@.*", Pattern.CASE_INSENSITIVE)); // @符号
|
||||
XSS_PATTERNS.add(Pattern.compile("!.*", Pattern.CASE_INSENSITIVE)); // 感叹号
|
||||
XSS_PATTERNS.add(Pattern.compile("%", Pattern.CASE_INSENSITIVE)); // %
|
||||
// 注意:@、!、% 这三个模式被移到 IGNORE_SPECIAL_PATTERNS 中,不在 XSS_PATTERNS 中
|
||||
|
||||
// 十六进制编码
|
||||
XSS_PATTERNS.add(Pattern.compile("\\\\x3c", Pattern.CASE_INSENSITIVE)); // < 的十六进制
|
||||
|
|
@ -271,11 +284,19 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
|
|||
}
|
||||
|
||||
String cleanedValue = value;
|
||||
// 使用预编译的模式
|
||||
|
||||
// 首先使用主要XSS模式进行清理
|
||||
for (Pattern pattern : XSS_PATTERNS) {
|
||||
cleanedValue = pattern.matcher(cleanedValue).replaceAll("");
|
||||
}
|
||||
|
||||
// 如果不是修改密码请求,才对特殊字符进行清理
|
||||
if (!isPasswordUpdateRequest()) {
|
||||
for (Pattern pattern : IGNORE_SPECIAL_PATTERNS) {
|
||||
cleanedValue = pattern.matcher(cleanedValue).replaceAll("");
|
||||
}
|
||||
}
|
||||
|
||||
// 如果值被修改,记录非法参数
|
||||
if (!cleanedValue.equals(value)) {
|
||||
recordIllegalParameter(paramName, value, cleanedValue, "XSS_ATTACK");
|
||||
|
|
@ -295,15 +316,42 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
|
|||
return isJsonSafe(paramName, value);
|
||||
}
|
||||
|
||||
// 使用预编译的模式进行检查
|
||||
boolean isSafe = true;
|
||||
|
||||
// 使用预编译的模式进行检查(主要XSS模式)
|
||||
for (Pattern pattern : XSS_PATTERNS) {
|
||||
if (match(pattern, value)) {
|
||||
// 发现XSS攻击,记录非法参数
|
||||
recordIllegalParameter(paramName, value, null, "XSS_PATTERN_" + pattern.pattern());
|
||||
return false;
|
||||
isSafe = false;
|
||||
}
|
||||
}
|
||||
return true; // 安全
|
||||
|
||||
// 如果不是修改密码请求,才对特殊字符进行检查
|
||||
if (!isPasswordUpdateRequest()) {
|
||||
for (Pattern pattern : IGNORE_SPECIAL_PATTERNS) {
|
||||
if (match(pattern, value)) {
|
||||
recordIllegalParameter(paramName, value, null, "SPECIAL_CHAR_PATTERN_" + pattern.pattern());
|
||||
isSafe = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isSafe;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为修改密码请求
|
||||
*/
|
||||
private boolean isPasswordUpdateRequest() {
|
||||
String requestURI = ((HttpServletRequest) getRequest()).getRequestURI();
|
||||
for (String url : IGNORE_SPECIAL_CHARS_URLS) {
|
||||
if (requestURI.contains(url)) {
|
||||
log.debug("检测到修改密码请求,忽略特殊字符校验: {}", requestURI);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查字符串是否为JSON格式
|
||||
|
|
@ -420,13 +468,25 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
|
|||
}
|
||||
|
||||
boolean isSafe = true;
|
||||
|
||||
// 检查主要XSS模式
|
||||
for (Pattern pattern : XSS_PATTERNS) {
|
||||
if (match(pattern, value)) {
|
||||
recordIllegalParameter(paramName, value, null, "XSS_PATTERN_" + pattern.pattern());
|
||||
isSafe = false;
|
||||
// 继续检查其他模式,记录所有匹配的攻击模式
|
||||
}
|
||||
}
|
||||
|
||||
// 如果不是修改密码请求,才对特殊字符进行检查
|
||||
if (!isPasswordUpdateRequest()) {
|
||||
for (Pattern pattern : IGNORE_SPECIAL_PATTERNS) {
|
||||
if (match(pattern, value)) {
|
||||
recordIllegalParameter(paramName, value, null, "SPECIAL_CHAR_PATTERN_" + pattern.pattern());
|
||||
isSafe = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isSafe;
|
||||
}
|
||||
|
||||
|
|
@ -441,6 +501,11 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
|
|||
* 记录非法参数信息
|
||||
*/
|
||||
private void recordIllegalParameter(String paramName, String originalValue, String cleanedValue, String attackType) {
|
||||
// 如果是修改密码请求,且攻击类型是特殊字符,则不记录
|
||||
if (isPasswordUpdateRequest() && attackType.startsWith("SPECIAL_CHAR_PATTERN_")) {
|
||||
return; // 忽略记录特殊字符攻击
|
||||
}
|
||||
|
||||
IllegalParameter illegalParam = new IllegalParameter();
|
||||
illegalParam.setParamName(paramName);
|
||||
illegalParam.setOriginalValue(originalValue);
|
||||
|
|
@ -452,11 +517,12 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
|
|||
|
||||
illegalParameters.add(illegalParam);
|
||||
|
||||
// 记录警告日志
|
||||
/*log.warn("检测到XSS攻击尝试 - 参数: {}, 攻击类型: {}, 原始值: {}, 客户端IP: {}",
|
||||
paramName, attackType,
|
||||
originalValue.length() > 100 ? originalValue.substring(0, 100) + "..." : originalValue,
|
||||
illegalParam.getClientIp());*/
|
||||
// 记录警告日志(特殊字符攻击在修改密码时不记录)
|
||||
if (!(isPasswordUpdateRequest() && attackType.startsWith("SPECIAL_CHAR_PATTERN_"))) {
|
||||
log.warn("检测到安全威胁 - 参数: {}, 攻击类型: {}, 原始值: {}",
|
||||
paramName, attackType,
|
||||
originalValue.length() > 100 ? originalValue.substring(0, 100) + "..." : originalValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -527,6 +593,5 @@ public class XssRequestWrapper extends HttpServletRequestWrapper {
|
|||
private Date detectedTime; // 检测时间
|
||||
private String requestUrl; // 请求URL
|
||||
private String clientIp; // 客户端IP
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue