diff --git a/common/src/main/java/com/jeesite/common/codec/EncodeUtils.java b/common/src/main/java/com/jeesite/common/codec/EncodeUtils.java
index ab0a8ba6..1e048a12 100644
--- a/common/src/main/java/com/jeesite/common/codec/EncodeUtils.java
+++ b/common/src/main/java/com/jeesite/common/codec/EncodeUtils.java
@@ -35,9 +35,9 @@ import java.util.regex.Pattern;
* @version 2022-2-17
*/
public class EncodeUtils {
-
+
public static final String UTF_8 = "UTF-8";
-
+
private static final Logger logger = LoggerFactory.getLogger(EncodeUtils.class);
private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
@@ -65,7 +65,7 @@ public class EncodeUtils {
public static String encodeBase64(byte[] input) {
return new String(Base64.encodeBase64(input));
}
-
+
/**
* Base64编码.
*/
@@ -97,7 +97,7 @@ public class EncodeUtils {
throw ExceptionUtils.unchecked(e);
}
}
-
+
/**
* Base64解码.
*/
@@ -152,14 +152,14 @@ public class EncodeUtils {
}
/**
- * URL 编码, Encode默认为UTF-8.
+ * URL 编码, Encode默认为UTF-8.
*/
public static String encodeUrl(String part) {
return encodeUrl(part, EncodeUtils.UTF_8);
}
/**
- * URL 编码, Encode默认为UTF-8.
+ * URL 编码, Encode默认为UTF-8.
*/
public static String encodeUrl(String part, String encoding) {
if (part == null){
@@ -173,14 +173,14 @@ public class EncodeUtils {
}
/**
- * URL 解码, Encode默认为UTF-8.
+ * URL 解码, Encode默认为UTF-8.
*/
public static String decodeUrl(String part) {
return decodeUrl(part, EncodeUtils.UTF_8);
}
/**
- * URL 解码, Encode默认为UTF-8.
+ * URL 解码, Encode默认为UTF-8.
*/
public static String decodeUrl(String part, String encoding) {
if (part == null){
@@ -192,9 +192,9 @@ public class EncodeUtils {
throw ExceptionUtils.unchecked(e);
}
}
-
+
/**
- * URL 解码(两次), Encode默认为UTF-8.
+ * URL 解码(两次), Encode默认为UTF-8.
*/
public static String decodeUrl2(String part) {
return decodeUrl(decodeUrl(part));
@@ -207,7 +207,7 @@ public class EncodeUtils {
Pattern.compile("\\s*on[a-z]+\\s*=\\s*(\"[^\"]+\"|'[^']+'|[^\\s]+)\\s*(?=>)", Pattern.CASE_INSENSITIVE),
Pattern.compile("(eval\\((.*?)\\)|xpression\\((.*?)\\))", Pattern.CASE_INSENSITIVE),
Pattern.compile("^(javascript:|vbscript:)", Pattern.CASE_INSENSITIVE)
- );
+ );
/**
* XSS 非法字符过滤,内容以开头的用以下规则(保留标签)
@@ -216,12 +216,16 @@ public class EncodeUtils {
public static String xssFilter(String text) {
return xssFilter(text, null);
}
-
+
/**
* XSS 非法字符过滤,内容以开头的用以下规则(保留标签)
* @author ThinkGem
*/
public static String xssFilter(String text, HttpServletRequest request) {
+ request = (request != null ? request : ServletUtils.getRequest());
+ if (request != null && StringUtils.containsAny(request.getRequestURI(), ServletUtils.XSS_FILE_EXCLUDE_URI)) {
+ return text;
+ }
String oriValue = StringUtils.trim(text);
if (text != null){
String value = oriValue;
@@ -232,39 +236,37 @@ public class EncodeUtils {
}
}
// 如果开始不是HTML,XML,JOSN格式,则再进行HTML的 "、<、> 转码。
- if (!StringUtils.startsWithIgnoreCase(value, "") // HTML
- && !StringUtils.startsWithIgnoreCase(value, "") // HTML
+ && !StringUtils.startsWithIgnoreCase(value, "':
- sb.append(">");
- break;
- case '<':
- sb.append("<");
- break;
- case '\'':
- sb.append("'");
- break;
- case '\"':
- sb.append(""");
- break;
-// case '&':
-// sb.append("&");
-// break;
-// case '#':
-// sb.append("#");
-// break;
- default:
- sb.append(c);
- break;
+ case '>':
+ sb.append(">");
+ break;
+ case '<':
+ sb.append("<");
+ break;
+ case '\'':
+ sb.append("'");
+ break;
+ case '\"':
+ sb.append(""");
+ break;
+// case '&':
+// sb.append("&");
+// break;
+// case '#':
+// sb.append("#");
+// break;
+ default:
+ sb.append(c);
+ break;
}
}
value = sb.toString();
@@ -277,12 +279,12 @@ public class EncodeUtils {
}
return null;
}
-
+
// 预编译SQL过滤正则表达式
private static Pattern sqlPattern = Pattern.compile(
"(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|((extractvalue|updatexml|if|mid|database|rand|user)([\\s]*?)\\()|"
- + "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|"
- + "drop|execute|case when|sleep|union|load_file)\\b)",
+ + "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|"
+ + "drop|execute|case when|sleep|union|load_file)\\b)",
Pattern.CASE_INSENSITIVE);
private static Pattern orderByPattern = Pattern.compile("[a-z0-9_\\.\\, ]*", Pattern.CASE_INSENSITIVE);
@@ -293,6 +295,7 @@ public class EncodeUtils {
public static String sqlFilter(String text){
return sqlFilter(text, "common");
}
+
/**
* SQL过滤,防止注入,传入参数输入有select相关代码,替换空。
* @author ThinkGem
@@ -319,7 +322,7 @@ public class EncodeUtils {
}
return null;
}
-
+
// public static void main(String[] args) {
// xssFilter("1 你好 我还在。");
// xssFilter("2 你好 加粗文字我还在。");
@@ -353,5 +356,5 @@ public class EncodeUtils {
// sqlFilter("5 if(1=2,1,SLEEP(10)), if(mid(database(),{},1)=\\\"{}\\\",a.id,a.login_name)", "orderBy");
// sqlFilter("6 a.audit_result asc, b.audit_result2 desc, b.AuditResult3 desc", "orderBy");
// }
-
+
}
diff --git a/common/src/main/java/com/jeesite/common/web/http/ServletUtils.java b/common/src/main/java/com/jeesite/common/web/http/ServletUtils.java
index 91d14f61..1494ee89 100644
--- a/common/src/main/java/com/jeesite/common/web/http/ServletUtils.java
+++ b/common/src/main/java/com/jeesite/common/web/http/ServletUtils.java
@@ -38,6 +38,9 @@ public class ServletUtils {
private static final String[] STATIC_FILE = StringUtils.splitComma(PROPS.getProperty("web.staticFile"));
private static final String[] STATIC_FILE_EXCLUDE_URI = StringUtils.splitComma(PROPS.getProperty("web.staticFileExcludeUri"));
+ // XSS 过滤器要排除的URI地址
+ public static final String[] XSS_FILE_EXCLUDE_URI = StringUtils.splitComma(PROPS.getProperty("web.xssFilterExcludeUri"));
+
// AJAX 请求参数和请求头名
public static final String AJAX_PARAM_NAME = PROPS.getProperty("web.ajaxParamName", "__ajax");
public static final String AJAX_HEADER_NAME = PROPS.getProperty("web.ajaxHeaderName", "x-ajax");
@@ -125,12 +128,8 @@ public class ServletUtils {
e.printStackTrace();
}
}
- if (STATIC_FILE_EXCLUDE_URI != null){
- for (String s : STATIC_FILE_EXCLUDE_URI){
- if (StringUtils.contains(uri, s)){
- return false;
- }
- }
+ if (StringUtils.containsAny(uri, STATIC_FILE_EXCLUDE_URI)) {
+ return false;
}
if (StringUtils.endsWithAny(uri, STATIC_FILE)){
return true;
diff --git a/modules/core/src/main/resources/config/jeesite-core.yml b/modules/core/src/main/resources/config/jeesite-core.yml
index 9b4be5c9..1c41f2e3 100644
--- a/modules/core/src/main/resources/config/jeesite-core.yml
+++ b/modules/core/src/main/resources/config/jeesite-core.yml
@@ -645,7 +645,10 @@ web:
# 严格模式(更严格的数据安全验证)
strictMode: false
-
+
+ # 所有请求信息将进行xss过滤,这里列出不被xss过滤的地址
+ xssFilterExcludeUri: /ureport/,/visual/
+
# 自定义正则表达式验证(主键、登录名)
validator:
id: '[a-zA-Z0-9_\-/#\u4e00-\u9fa5]{0,64}'
diff --git a/web-api/src/main/resources/config/application.yml b/web-api/src/main/resources/config/application.yml
index b218c6d7..06bc0af3 100644
--- a/web-api/src/main/resources/config/application.yml
+++ b/web-api/src/main/resources/config/application.yml
@@ -786,6 +786,9 @@ web:
#
# # 严格模式(更严格的数据安全验证)
# strictMode: false
+#
+# # 所有请求信息将进行xss过滤,这里列出不被xss过滤的地址
+# xssFilterExcludeUri: /ureport/,/visual/
#
# # 自定义正则表达式验证(主键、登录名)
# validator:
diff --git a/web/src/main/resources/config/application.yml b/web/src/main/resources/config/application.yml
index f516bd41..1f98dac3 100644
--- a/web/src/main/resources/config/application.yml
+++ b/web/src/main/resources/config/application.yml
@@ -787,6 +787,9 @@ web:
# # 严格模式(更严格的数据安全验证)
# strictMode: false
#
+# # 所有请求信息将进行xss过滤,这里列出不被xss过滤的地址
+# xssFilterExcludeUri: /ureport/,/visual/
+#
# # 自定义正则表达式验证(主键、登录名)
# validator:
# id: '[a-zA-Z0-9_\-/#\u4e00-\u9fa5]{0,64}'