From b1fcf4723add2739124e5ac95852e8b315e9077d Mon Sep 17 00:00:00 2001 From: sxile <3440626@qq.com> Date: Tue, 12 Nov 2019 11:15:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=BB=E6=8E=89jsoup=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E8=BD=AC=E4=B9=89=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 10 +- ruoyi-common/pom.xml | 8 +- .../ruoyi/common/utils/html/EscapeUtil.java | 152 ++++++++++++++++++ .../xss/XssHttpServletRequestWrapper.java | 7 +- 4 files changed, 157 insertions(+), 20 deletions(-) create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java diff --git a/pom.xml b/pom.xml index 22ad751..da42920 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,6 @@ 3.9.1 2.5 1.3.3 - 1.11.3 3.17 1.7 @@ -147,14 +146,7 @@ commons-fileupload ${commons.fileupload.version} - - - - org.jsoup - jsoup - ${jsoup.version} - - + org.apache.poi diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index 7142ec6..24e2654 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -76,13 +76,7 @@ commons-fileupload commons-fileupload - - - - org.jsoup - jsoup - - + org.apache.poi diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java new file mode 100644 index 0000000..f49211d --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java @@ -0,0 +1,152 @@ +package com.ruoyi.common.utils.html; + +import com.ruoyi.common.utils.StringUtils; + +/** + * 转义和反转义工具类 + * + * @author ruoyi + */ +public class EscapeUtil +{ + public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"; + + private static final char[][] TEXT = new char[64][]; + + static + { + for (int i = 0; i < 64; i++) + { + TEXT[i] = new char[] { (char) i }; + } + + // special HTML characters + TEXT['\''] = "'".toCharArray(); // 单引号 + TEXT['"'] = """.toCharArray(); // 单引号 + TEXT['&'] = "&".toCharArray(); // &符 + TEXT['<'] = "<".toCharArray(); // 小于号 + TEXT['>'] = ">".toCharArray(); // 大于号 + } + + /** + * 转义文本中的HTML字符为安全的字符 + * + * @param text 被转义的文本 + * @return 转义后的文本 + */ + public static String escape(String text) + { + return encode(text); + } + + /** + * 还原被转义的HTML特殊字符 + * + * @param content 包含转义符的HTML内容 + * @return 转换后的字符串 + */ + public static String unescape(String content) + { + return decode(content); + } + + /** + * 清除所有HTML标签,但是不删除标签内的内容 + * + * @param content 文本 + * @return 清除标签后的文本 + */ + public static String clean(String content) + { + return content.replaceAll(RE_HTML_MARK, ""); + } + + /** + * Escape编码 + * + * @param text 被编码的文本 + * @return 编码后的字符 + */ + private static String encode(String text) + { + int len; + if ((text == null) || ((len = text.length()) == 0)) + { + return StringUtils.EMPTY; + } + StringBuilder buffer = new StringBuilder(len + (len >> 2)); + char c; + for (int i = 0; i < len; i++) + { + c = text.charAt(i); + if (c < 64) + { + buffer.append(TEXT[c]); + } + else + { + buffer.append(c); + } + } + return buffer.toString(); + } + + /** + * Escape解码 + * + * @param content 被转义的内容 + * @return 解码后的字符串 + */ + public static String decode(String content) + { + if (StringUtils.isEmpty(content)) + { + return content; + } + + StringBuilder tmp = new StringBuilder(content.length()); + int lastPos = 0, pos = 0; + char ch; + while (lastPos < content.length()) + { + pos = content.indexOf("%", lastPos); + if (pos == lastPos) + { + if (content.charAt(pos + 1) == 'u') + { + ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16); + tmp.append(ch); + lastPos = pos + 6; + } + else + { + ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16); + tmp.append(ch); + lastPos = pos + 3; + } + } + else + { + if (pos == -1) + { + tmp.append(content.substring(lastPos)); + lastPos = content.length(); + } + else + { + tmp.append(content.substring(lastPos, pos)); + lastPos = pos; + } + } + } + return tmp.toString(); + } + + public static void main(String[] args) + { + String html = ""; + System.out.println(EscapeUtil.clean(html)); + System.out.println(EscapeUtil.escape(html)); + System.out.println(EscapeUtil.unescape(html)); + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java b/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java index 68ff57e..c59b7f5 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java @@ -2,9 +2,7 @@ package com.ruoyi.common.xss; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; -import org.jsoup.Jsoup; -import org.jsoup.safety.Whitelist; - +import com.ruoyi.common.utils.html.EscapeUtil; /** * XSS过滤处理 * @@ -31,7 +29,8 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper for (int i = 0; i < length; i++) { // 防xss攻击和过滤前后空格 - escapseValues[i] = Jsoup.clean(values[i], Whitelist.relaxed()).trim(); + escapseValues[i] = EscapeUtil.clean(values[i]).trim(); + } return escapseValues; }