springMVC如何使用Filter实现防止xss注入呢?
下文笔者讲述SpringMVC中实现XSS注入的方法分享,如下所示
XSS简介
XSS: 跨站脚本攻击(Cross Site Scripting) 为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆 故将跨站脚本攻击缩写为XSS 恶意攻击者往Web页面里插入恶意html代码 当用户浏览该页之时 嵌入其中Web里面的html代码会被执行 从而达到恶意攻击浏览者的效果 XSS脚本对访问者有一定的伤害
sql注入
SQL注入: 通过将SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串 最终达到欺骗服务器运行恶意SQL命令 通俗的讲: 使用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力 它可通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库
避免XSS攻击的原理: 对Request请求中的一些参数去掉一些比较敏感的脚本命令 XSS攻击避免的方法: 使用springMVC的HandlerInterceptor机制来实现 通过获取request然后对request中的参数进行修改 实现参数值的修改,达到参数过滤的效果例:
1.先配置web.xml,添加如下配置信息: <!-- Filter实现防止xss注入 --> <filter> <filter-name>MyXssFilter</filter-name> <filter-class>com.java265.common.filter.MyXssFilter</filter-class> </filter> <filter-mapping> <filter-name>MyXssFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 2.编写过滤器 /** * @Description: 获取参数时对参数进行XSS判断预防 * @Author java265.com * @Date 2023/1/4 */ @WebFilter(filterName="xssMyfilter",urlPatterns="/*") public class MyXssFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { XsslHttpServletRequestWrapper xssRequest = new XsslHttpServletRequestWrapper((HttpServletRequest)request); chain.doFilter(xssRequest , response); } @Override public void destroy() { } } XSS代码的过滤是在XsslHttpServletRequestWrapper中实现的 主要是覆盖实现了getParameter,getParameterValues,getHeader这几个方法,然后对获取的value值进行XSS处理。 import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.regex.Pattern; /** * @Description: XSS代码的过滤是在XsslHttpServletRequestWrapper中实现的, * 主要是覆盖实现了getParameter,getParameterValues,getHeader这几个方法, * 然后对获取的value值进行XSS处理 * @Author java265.com * @Date 2023/1/4 */ public class XsslHttpServletRequestWrapper extends HttpServletRequestWrapper { HttpServletRequest xssRequest = null; public XsslHttpServletRequestWrapper(HttpServletRequest request) { super(request); xssRequest = request; } @Override public String getParameter(String name) { String value = super.getParameter(replaceXSS(name)); if (value != null) { value = replaceXSS(value); } return value; } @Override public String[] getParameterValues(String name) { String[] values = super.getParameterValues(replaceXSS(name)); if(values != null && values.length > 0){ for(int i =0; i< values.length ;i++){ values[i] = replaceXSS(values[i]); } } return values; } /** * 覆盖getHeader方法,将参数名和参数值都做xss & sql过滤。<br/> * 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/> * getHeaderNames 也可能需要覆盖 */ @Override public String getHeader(String name) { String value = super.getHeader(replaceXSS(name)); if (value != null) { value = replaceXSS(value); } return value; } /** * 去除待带script、src、img的语句,转义替换后的value值 */ public static String replaceXSS(String value) { if (value != null) { try{ value = value.replace("+","%2B"); //'+' replace to '%2B' value = URLDecoder.decode(value, "utf-8"); }catch(UnsupportedEncodingException e){ }catch(IllegalArgumentException e){ } // Avoid null characters value = value.replaceAll("\0", ""); // Avoid anything between script tags Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<img>(.*?)</img>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); // Avoid anything in a src='...' type of e-xpression scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); // Remove any lonesome </script> tag scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); // Remove any lonesome </script> tag scriptPattern = Pattern.compile("</img>", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); // Remove any lonesome <script ...> tag scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("<img(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); // Avoid eval(...) e-xpressions scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); // Avoid e-xpression(...) e-xpressions scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); // Avoid javascript:... e-xpressions scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); // Avoid alert:... e-xpressions scriptPattern = Pattern.compile("alert", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); // Avoid onload= e-xpressions scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE); value = scriptPattern.matcher(value).replaceAll(""); } return filter(value); } /** * 过滤特殊字符 */ public static String filter(String value) { if (value == null) { return null; } StringBuffer result = new StringBuffer(value.length()); for (int i=0; i<value.length(); ++i) { switch (value.charAt(i)) { case '<': result.append("<"); break; case '>': result.append(">"); break; case '"': result.append("\""); break; case '\'': result.append("'"); break; case '%': result.append("%"); break; case ';': result.append(";"); break; case '(': result.append("("); break; case ')': result.append(")"); break; case '&': result.append("&"); break; case '+': result.append("+"); break; default: result.append(value.charAt(i)); break; } } return result.toString(); } }
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。