1. 程式人生 > >WEB安全掃描解決 XSS 攻擊的解決方案

WEB安全掃描解決 XSS 攻擊的解決方案

xss(跨站指令碼攻擊)

跨站指令碼攻擊(Cross Site Scripting),為了不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站指令碼攻擊縮寫為XSS。惡意攻擊者往Web頁面裡插入惡意Script程式碼,當用戶瀏覽該頁之時,嵌入其中Web裡面的Script程式碼會被執行,從而達到惡意攻擊使用者的目的。

新方案

對於出現的問題,我這裡有兩點需要說,其一就是針對後臺的驗證邏輯,這個沒有必要再詳細說了,無非就行完善驗證邏輯,針對可能出現的情況進行抽象,抽出通用的驗證邏輯,對於個別的驗證就單獨處理,不過還是要考慮程式碼的複用性。

其二,是關於 XSS 攻擊全域性處理的。我這裡給出兩種解決方案,詳述如下。

方案一

如果你遇到的情況,對與使用者的輸入、輸出有明確的限制,而且對於特殊字元也有明確的規定,那麼你可以自己寫一個 XSSFilter,使用上面提到的情況二,對不建議輸入的特殊字元進行過濾和清理,包括 SQL 注入的一些敏感資訊,都是要過濾掉的。基本的 Filter 網上都有,你要做的就是針對自己的業務,再加入對危險字元的處理即可。

方案二

想到一句老話,站在巨人的肩膀上。第二種方案,就是站在巨人的肩膀上。推薦一款開源外掛,xssProject,具體作者不詳。GoogleCode 中提供相應了的原始碼。想研究的可以自己去找一下。下面著重講一下,如何在專案中整合 xssProject,並使之為我們服務。

首先,專案中需要引入 xssProtect-0.1.jar、antlr-3.0.1.jar、antlr-runtime-3.0.1.jar 等3個 jar 包。

然後,封裝 request,程式碼如下。

public class NewXssHttpServletRequestWrapper extends HttpServletRequestWrapper {
 
	HttpServletRequest orgRequest = null;
	
	public NewXssHttpServletRequestWrapper(HttpServletRequest request) {
		super(request);
        orgRequest = request;
	}
	
 
    /**
     * 覆蓋getParameter方法,將引數名和引數值都做xss過濾。<br/>
     * 如果需要獲得原始的值,則通過super.getParameterValues(name)來獲取<br/>
     * getParameterNames,getParameterValues和getParameterMap也可能需要覆蓋
     */
    @Override
    public String getParameter(String name)
    {
    	System.out.println("NewXssFilter處理前的 Value = " + super.getParameterValues(name));
    	
        String value = super.getParameter(xssEncode(name));
        if (value != null)
        {
            value = xssEncode(value);
        }
        
        System.out.println("NewXssFilter處理後的 Value = " + value);
        
        return value;
    }
 
    /**
     * 覆蓋getHeader方法,將引數名和引數值都做xss過濾。<br/>
     * 如果需要獲得原始的值,則通過super.getHeaders(name)來獲取<br/> getHeaderNames 也可能需要覆蓋
     */
    @Override
    public String getHeader(String name)
    {
 
        String value = super.getHeader(xssEncode(name));
        if (value != null)
        {
            value = xssEncode(value);
        }
        return value;
    }
 
    /**
     * 將容易引起xss漏洞的半形字元直接替換成全形字元
     * 
     * @param s
     * @return
     */
    private static String xssEncode(String s)
    {
        if (s == null || s.isEmpty())
        {
            return s;
        }
        
        StringReader reader = new StringReader( s );
        StringWriter writer = new StringWriter();
        try {
            HTMLParser.process( reader, writer, new XSSFilter(), true );
            
            return writer.toString();
        } 
        catch (NullPointerException e) {
            return s;
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        
        return null;
        
    }
 
    /**
     * 獲取最原始的request
     * 
     * @return
     */
    public HttpServletRequest getOrgRequest()
    {
        return orgRequest;
    }
 
    /**
     * 獲取最原始的request的靜態方法
     * 
     * @return
     */
    public static HttpServletRequest getOrgRequest(HttpServletRequest req)
    {
        if (req instanceof NewXssHttpServletRequestWrapper)
        {
            return ((NewXssHttpServletRequestWrapper) req).getOrgRequest();
        }
 
        return req;
    }
 
}

再然後,建立過濾器 NewXssFilter 。

public class NewXssFilter implements Filter {
 
	FilterConfig filterConfig = null;
 
	@Override
	public void destroy() {
		this.filterConfig = null;
	}
 
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		String path = ((HttpServletRequest) request).getContextPath();
		String basePath = request.getScheme() + "://" + request.getServerName()
				+ ":" + request.getServerPort() + path + "/";
 
		// HTTP 頭設定 Referer過濾
		String referer = ((HttpServletRequest) request).getHeader("Referer"); // REFRESH
		if (referer != null && referer.indexOf(basePath) < 0) {
			((HttpServletRequest) request).getRequestDispatcher(
					((HttpServletRequest) request).getRequestURI()).forward(
					((HttpServletRequest) request), response);
			System.out.println("referer不為空,referer >>>>>>>>>>>>>> " + referer);
		}
		NewXssHttpServletRequestWrapper xssRequest = new NewXssHttpServletRequestWrapper((HttpServletRequest) request);
		chain.doFilter(xssRequest, response);
	}
 
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
	}
 
}

最後,在 web.xml 中配置過濾器 。

<filter>
	<filter-name>XssSqlFilter</filter-name>
	<filter-class>com.***.web.common.NewXssFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>XssSqlFilter</filter-name>
	<url-pattern>/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
</filter-mapping>

以上這些就是全部的內容了,針對 XSS 攻擊的解決方案,寫出來跟大家分享,個人建議使用 xssProject 來解決這一問題。畢竟 xssProject 已經提供了很完善的過濾、處理方案,你可以通過研究他的程式碼來進行擴充套件,如果需要的話。最後附上 xssProject 所需的三個 jar 包。