XSSEscape.java 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. package jnpf.util;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.owasp.validator.html.AntiSamy;
  4. import org.owasp.validator.html.CleanResults;
  5. import org.owasp.validator.html.Policy;
  6. import org.springframework.util.ObjectUtils;
  7. import java.io.InputStream;
  8. import java.util.regex.Matcher;
  9. import java.util.regex.Pattern;
  10. /**
  11. * 防止XSS注入
  12. *
  13. * @author JNPF开发平台组
  14. * @version V3.1.0
  15. * @copyright 引迈信息技术有限公司(https://www.jnpfsoft.com)
  16. * @date 2021-12-07
  17. */
  18. @Slf4j
  19. public class XSSEscape {
  20. /**
  21. * 非法路径符号
  22. */
  23. private static final Pattern PATH_PATTERN = Pattern.compile("\\.\\.|~[/\\\\]|[<]|>|\"|[*]|[|]|[?]", Pattern.CASE_INSENSITIVE);
  24. private static InputStream inputStream;
  25. private static Policy policy;
  26. private static Policy emptyPolicy;
  27. private static Policy imgOnlyBase64Policy;
  28. static{
  29. try{
  30. inputStream = XSSEscape.class.getClassLoader().getResourceAsStream("antisamy-ebay.xml");
  31. policy = Policy.getInstance(inputStream);
  32. inputStream.close();
  33. inputStream = XSSEscape.class.getClassLoader().getResourceAsStream("antisamy-ebay-imgonlybase64.xml" );
  34. imgOnlyBase64Policy = Policy.getInstance(inputStream);
  35. inputStream.close();
  36. inputStream = XSSEscape.class.getClassLoader().getResourceAsStream("antisamy-empty.xml");
  37. emptyPolicy = Policy.getInstance(inputStream);
  38. inputStream.close();
  39. }catch (Exception e){
  40. e.printStackTrace();
  41. }
  42. }
  43. /**
  44. * 跨站式脚本攻击字符串过滤
  45. * @param character 需要转义的字符串
  46. */
  47. public static String escape(String character) {
  48. if(StringUtil.isBlank(character)){
  49. return character;
  50. }
  51. try {
  52. AntiSamy antiSamy = new AntiSamy();
  53. String str = character.replaceAll("&quot;", "\"");
  54. str = str.replaceAll("&amp;", "&");
  55. str = str.replaceAll("&lt;", "<");
  56. str = str.replaceAll("&gt;", ">");
  57. str = str.replaceAll("&nbsp;", " ");
  58. CleanResults scan = antiSamy.scan(str, policy);
  59. str = scan.getCleanHTML();
  60. return str;
  61. } catch (Exception e) {
  62. log.error("转换错误:" + e.getMessage());
  63. }
  64. return null;
  65. }
  66. /**
  67. * 跨站式脚本攻击字符串过滤(图片标签只允许base64格式)
  68. * @param character 需要转义的字符串
  69. */
  70. public static String escapeImgOnlyBase64(String character) {
  71. if(StringUtil.isBlank(character)){
  72. return character;
  73. }
  74. try {
  75. AntiSamy antiSamy = new AntiSamy();
  76. String str = character.replaceAll("&quot;", "\"");
  77. str = str.replaceAll("&amp;", "&");
  78. str = str.replaceAll("&lt;", "<");
  79. str = str.replaceAll("&gt;", ">");
  80. str = str.replaceAll("&nbsp;", " ");
  81. CleanResults scan = antiSamy.scan(str, imgOnlyBase64Policy);
  82. str = scan.getCleanHTML();
  83. return str;
  84. } catch (Exception e) {
  85. log.error("转换错误:" + e.getMessage());
  86. }
  87. return null;
  88. }
  89. /**
  90. * 此方法伪过滤
  91. * @param character 需要转义的字符串
  92. */
  93. public static <T> T escapeObj(T character) {
  94. try {
  95. if(ObjectUtils.isEmpty(character)){
  96. return character;
  97. }
  98. String str = escapeEmpty(JsonUtil.getObjectToString(character));
  99. if(ObjectUtils.isEmpty(str.trim())){
  100. return character;
  101. }
  102. return (T) JsonUtil.getJsonToBean(str, character.getClass());
  103. } catch (Exception e) {
  104. }
  105. return character;
  106. }
  107. /**
  108. * 此方法伪过滤
  109. * @param character 需要转义的字符串
  110. */
  111. public static String escapeEmpty(String character) {
  112. if(StringUtil.isBlank(character)){
  113. return character;
  114. }
  115. try {
  116. AntiSamy antiSamy = new AntiSamy();
  117. CleanResults scan = antiSamy.scan(character, emptyPolicy);
  118. return scan.getCleanHTML();
  119. } catch (Exception e) {
  120. }
  121. return character;
  122. }
  123. /**
  124. * 过滤非法路径
  125. * @param path
  126. * @return
  127. */
  128. public static String escapePath(String path){
  129. if(StringUtil.isBlank(path)){
  130. return path;
  131. }
  132. Matcher matcher;
  133. while((matcher = PATH_PATTERN.matcher(path)).find()){
  134. path = matcher.replaceAll("");
  135. }
  136. return escapeEmpty(path);
  137. }
  138. }