1. 程式人生 > >WEB安全實戰(三)XSS 攻擊的防禦

WEB安全實戰(三)XSS 攻擊的防禦


  • 方案二
第二種方案也是藉助外力,主要是加入一個第三方的 jar 包,然後使用第三方元件給提供的 api,我們通過呼叫這些 api 可以避免 XSS 攻擊帶來的危險。具體步驟如下。 首先,新增第三方的元件包,commons-lang-2.5.jar,可以手動下載,也可以使用 maven 配置依賴,管理 jar,推薦使用後者。 然後,在後臺呼叫這些函式,StringEscapeUtils.escapeHtml(string);StringEscapeUtils.escapeJavaScript(string);StringEscapeUtils.escapeSql(string); 最後,在前臺的 js 呼叫 escape 即可。
  • 方案三
接下來,主要講一下第三種方案,因為在第三種方案中,我們要自己寫一個 Filter,使用 Filter 來過濾瀏覽器發出的請求。對每個 post 請求的引數過濾一些關鍵字,替換成安全的,例如:< > ' " \ / # & 。方法是實現一個自定義的 HttpServletRequestWrapper,然後在 Filter 裡面呼叫它,替換掉 getParameter 函式即可,具體步驟如下。 首先,在後臺新增一個 XssHttpServletRequestWrapper 類,程式碼如下。
<span style="font-family:Comic Sans MS;">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;
    }

} </span>
然後,同樣在後臺新增一個過濾器 XssFilter,具體程式碼如下。
<span style="font-family:Comic Sans MS;">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);
    }
}</span>
最後,在 web.xml 裡面配置一下,所有請求的 getParameter 會被替換,如果引數裡面含有敏感詞會被替換掉。
<span style="font-family:Comic Sans MS;"><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></span>

到這裡,就基本完成了一個 XSS 攻擊防禦的隔離層。每一次請求中的危險字元、敏感資訊都會被過濾掉,當然,如果你需要過濾的字元有很多,你還可以在 cleanXSS 方法中補充,直到你滿意為止。當然,需要注意的是,一些必要的字元不能被過濾,否則就改變了使用者的真實資料。

一個例項

下面提供了一個登入頁面的攻擊例項,你可以通過下面的方式進行簡單的測試,看看你的網站是否有這樣的問題,當然,這只是最簡單的,那些測試工具肯定要比這樣的例子專業的多。很多隱藏的漏洞都能夠被測試出來。 假設登入頁面有個輸入使用者名稱和密碼的輸入框,可以有很多 XSS / CSRF / 注入釣魚網站 / SQL注入等的攻擊手段,例如:
<span style="font-family:Comic Sans MS;">輸入使用者名稱 : >"'><script>alert(1779)</script>
輸入使用者名稱: usera>"'><img src="javascript:alert(23664)">
輸入使用者名稱: "'><IMG SRC="/WF_XSRF.html--end_hig--begin_highlight_tag--hlight_tag--">
輸入使用者名稱: usera'"><iframe src=http://demo.testfire.net--en--begin_highlight_tag--d_highlight_tag-->

密碼隨意輸入。</span>