XSS攻击的简单防御

XSS(Cross Site Scripting)跨站脚本攻击,恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

方案一

主要是利用了 SpringMVC 的特性,使用 SpringMVC 内置的方法 defaultHtmlEscape,在 web.xml 中配置上 context-param,然后在 Form 中加入 spring 的标签,具体配置如下。

<context-param>  
   <param-name>defaultHtmlEscape</param-name>  
   <param-value>true</param-value>  
</context-param>

<spring:htmlEscape defaultHtmlEscape="true" />

方案二

第二种方案也是借助外力,主要是加入一个第三方的 jar 包,然后使用第三方组件给提供的 api,我们通过调用这些 api 可以避免 XSS 攻击带来的危险。具体步骤如下。

首先,添加第三方的组件包,commons-lang.jar,可以手动下载,也可以使用 maven 配置依赖,管理 jar,推荐使用后者。

然后,在后台调用这些函数,StringEscapeUtils.escapeHtml(string);StringEscapeUtils.escapeJavaScript(string);StringEscapeUtils.escapeSql(string);
最后,在前台的 js 调用 escape 即可。
方案三
接下来,主要讲一下第三种方案,因为在第三种方案中,我们要自己写一个 Filter,使用 Filter 来过滤浏览器发出的请求。对每个 post 请求的参数过滤一些关键字,替换成安全的,例如:< > ‘ ” \ / # & 。方法是实现一个自定义的 HttpServletRequestWrapper,然后在 Filter 里面调用它,替换掉 getParameter 函数即可,具体步骤如下。
首先,在后台添加一个 XssHttpServletRequestWrapper 类,代码如下。
package com.sic.web.beans;  
  
import java.util.Enumeration;  
  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletRequestWrapper;  
  
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {    
    public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {  
        super(servletRequest);  
    }  
    public String[] getParameterValues(String parameter) {  
      String[] values = super.getParameterValues(parameter);  
      if (values==null)  {  
                  return null;  
          }  
      int count = values.length;  
      String[] encodedValues = new String[count];  
      for (int i = 0; i < count; i++) {  
                 encodedValues[i] = cleanXSS(values[i]);  
       }  
      return encodedValues;  
    }  
    public String getParameter(String parameter) {  
          String value = super.getParameter(parameter);  
          if (value == null) {  
                 return null;  
                  }  
          return cleanXSS(value);  
    }  
    public String getHeader(String name) {  
        String value = super.getHeader(name);  
        if (value == null)  
            return null;  
        return cleanXSS(value);  
    }  
    private String cleanXSS(String value) {  
        value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");  
        value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");  
        value = value.replaceAll("'", "& #39;");  
        value = value.replaceAll("eval\\((.*)\\)", "");  
        value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");  
        value = value.replaceAll("script", "");  
        return value;  
    }  
  
}

然后,同样在后台添加一个过滤器 XssFilter,具体代码如下

package com.sic.web.beans;  
  
import java.io.IOException;    
  
import javax.servlet.Filter;    
import javax.servlet.FilterChain;    
import javax.servlet.FilterConfig;    
import javax.servlet.ServletException;    
import javax.servlet.ServletRequest;    
import javax.servlet.ServletResponse;    
import javax.servlet.http.HttpServletRequest;    
import javax.servlet.http.HttpServletResponse;  
  
public class XssFilter implements Filter {  
    FilterConfig filterConfig = null;  
  
    public void init(FilterConfig filterConfig) throws ServletException {  
        this.filterConfig = filterConfig;  
    }  
  
    public void destroy() {  
        this.filterConfig = null;  
    }  
  
    public void doFilter(ServletRequest request, ServletResponse response,  
            FilterChain chain) throws IOException, ServletException {  
        chain.doFilter(new XssHttpServletRequestWrapper(  
                (HttpServletRequest) request), response);  
    }  
}

最后,在 web.xml 里面配置一下,所有请求的 getParameter 会被替换,如果参数里面含有敏感词会被替换掉。

<filter>  
     <filter-name>XssSqlFilter</filter-name>  
     <filter-class>com.ibm.web.beans.XssFilter</filter-class>  
</filter>  
<filter-mapping>  
     <filter-name>XssSqlFilter</filter-name>  
     <url-pattern>/*</url-pattern>  
     <dispatcher>REQUEST</dispatcher>  
</filter-mapping>

到这里,就基本完成了一个 XSS 攻击防御的隔离层。每一次请求中的危险字符、敏感信息都会被过滤掉,当然,如果你需要过滤的字符有很多,你还可以在 cleanXSS 方法中补充,直到你满意为止。当然,需要注意的是,一些必要的字符不能被过滤,否则就改变了用户的真实数据。