使用AntiSamy防範XSS跨站腳本攻擊

0x00 什麼是XSS?

XSS(Cross Site Scripting),即跨站腳本攻擊,是一種常見於web application中的計算機安全漏洞。XSS通過在用戶端注入惡意的可運行腳本,若服務器端對用戶輸入不進行處理,直接將用戶輸入輸出到瀏覽器,則瀏覽器將會執行用戶注入的腳本。

 

0x01 XSS的分類

根據XSS造成的影響,可以將XSS分爲非持久型和持久型。

1.             非持久型,也叫反射型XSS。通過GET和 POST方法,向服務器端輸入數據。用戶輸入的數據通常被放置在URL的query string中,或者是form 數據中。如果服務器端對輸入的數據不進行過濾,驗證或編碼,就直接將用戶輸入的信息直接呈現給客戶,則可能會造成反射型XSS。反射型XSS是比較普遍的 XSS,其危害程度通常被認爲較小。但是某些反射型XSS造成的後果會很嚴重,如在輸入框的name中輸入<meta http-equiv="refresh" content="5" />,服務器不加處理,將name的值直接送到瀏覽器,則瀏覽器會每5秒自動刷新一次。嚴重者會導致服務器崩潰。

2.             持久型,也叫存儲型XSS。通常是因爲服務器端將用戶輸入的惡意腳本沒有通過驗證就直接存儲在數據庫,並且每次通過調用數據庫的方式,將數據呈現在瀏覽器上。則該 XSS跨站腳本攻擊將一直存在。若其他用戶訪問該頁面,則惡意腳本就會被觸發,用於盜取其他用戶的私人信息。

0x02 常用XSS方式分爲以下幾種:

1.      輸入框中直接輸入惡意腳本,如:

><script>alert(document.cookie)</script>

2.      輸入框中輸入html標籤,在標籤中嵌入惡意腳本,如src,href,css style等。

<IMG SRC="javascript:alert('XSS');">;

<BODY BACKGROUND="javascript:alert('XSS')">

<STYLE>li {list-style-image:url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS</br>

3.      將惡意腳本注入在event事件中,如onClick,onBlur,onMouseOver等事件。

<a onmouseover="alert(document.cookie)">xxslink</a>

4.      在remote style sheet,javascript中,如

<LINK REL="stylesheet"HREF="javascript:alert('XSS');">

<SCRIPT/SRC="http://ha.ckers.org/xss.js"></SCRIPT>

5.      META 標籤,如

<meta http-equiv="refresh"content="5" />

<META HTTP-EQUIV="Set-Cookie"Content="USERID=<SCRIPT>alert('XSS')</SCRIPT>">

 

0x03 AntiSamy介紹

OWASP是一個開源的、非盈利的全球性安全組織,致力於應用軟件的安全研究。我們的使命是使應用軟件更加安全,使企業和組織能夠對應用安全風險作出更清晰的決策。目前OWASP全球擁有140個分會近四萬名會員,共同推動了安全標準、安全測試工具、安全指導手冊等應用安全技術的發展。

OWASP AntiSamy項目可以有好幾種定義。從技術角度看,它是一個可確保用戶輸入的HTML/CSS符合應用規範的API。也可以這麼說,它是個確保用戶無法在HTML中提交惡意代碼的API,而這些惡意代碼通常被輸入到個人資料、評論等會被服務端存儲的數據中。在Web應用程序中,“惡意代碼”通常是指 Javascript。同時層疊樣式表(CSS)在調用Javascript引擎的時候也會被認爲是惡意代碼。當然在很多情況下,一些“正常”的HTML 和CSS也會被用於惡意的目的,所以我們也會對此予以處理。

 

0x04 AnitiSamy下載

         官方網站:https://www.owasp.org/index.php/Category:OWASP_AntiSamy_Project

         項目地址:https://code.google.com/p/owaspantisamy/downloads/list

                   我們看到Downloads,下載WhereToGet.txt就可以看到下載地址

 

0x05 標準策略文件說明

antisamy-slashdot.xml

Slashdot (  http://www.slashdot.org/  )  是一個提供技術新聞的網站,它允許用戶用有限  的  HTML  格式的內容匿名回帖。  Slashdot 不僅僅是目前同類中最酷的網站之一,而  且同時也曾是最容易被成功攻擊的網站之一。更不幸的是,導致大部分用戶遭受攻  擊的原由是臭名昭着的  goatse.cx  圖片  (  請你不要刻意去看  )  。  Slashdot 的安全策略非  常嚴格:用戶只能提交下列的  html  標籤:  <b>, <u>, <i>, <a>,<blockquote>  ,並且  還不支持  CSS. 

因此我們創建了這樣的策略文件來實現類似的功能。它允許所有文本格式的標籤來  直接修飾字體、顏色或者強調作用。

antisamy-ebay.xml

衆所周知,  eBay (  http://www.ebay.com/  )  是當下最流行的在線拍賣網站之一。它是一  個面向公衆的站點,因此它允許任何人發佈一系列富  HTML  的內容。  我們對  eBay  成爲一些複雜  XSS  攻擊的目標,並對攻擊者充滿吸引力絲毫不感到奇怪。由於  eBay  允許  輸入的內容列表包含了比  Slashdot 更多的富文本內容,所以它的受攻擊面也要大得多。下  面的標籤看起來是  eBay  允許的(  eBay  沒有公開標籤的驗證規則)  :     <a>,..

antisamy-myspace.xml

MySpace ( http://www.myspace.com/  )  是最流行的一個社交網站之一。用戶允許提交  幾乎所有的他們想用的  HTML  和  CSS  ,只要不包含  JavaScript 。  MySpace  現在用一  個黑名單來驗證用戶輸入的  HTML  ,這就是爲什麼它曾受到  Samy  蠕蟲攻擊  ( http://namb.la/)  的原因。  Samy  蠕蟲攻擊利用了一個本應該列入黑名單的單詞  (eval)  來進行組合碎片攻擊的,其實這也是  AntiSamy 立項的原因。  

antisamy-anythinggoes.xml 

也很難說出一個用這個策略文件的用例。如果你想允許所有有效的  HTML  和  CSS  元素輸入(但能拒絕  JavaScript 或跟  CSS  相關的網絡釣魚攻擊),你可以使用  這個策略文件。其實即使  MySpace 也沒有這麼瘋狂。然而,它確實提供了一個很  好的參考,因爲它包含了對於每個元素的基本規則,所以你在裁剪其它策略文件的  時候可以把它作爲一個知識庫。  

0x06 策略文件定製

http://www.owasp.org/index.php/AntiSamy_Directives

0x07 AntiSamy.JAVA的使用

首先,老規矩,我們需要一個jar包

使用Maven的,在pom.xml的dependencies中添加如下代碼

[html] view plain copy
  1. <dependency>  
  2.     <groupId>org.owasp.antisamy</groupId>  
  3.     <artifactId>antisamy</artifactId>  
  4.     <version>1.5.3</version>  
  5. </dependency>  

配置web.xml

[html] view plain copy
  1. <!-- XXS -->  
  2. <filter>  
  3.     <filter-name>XSS</filter-name>  
  4.     <filter-class>com.sinba.bugfix.XssFilter</filter-class>  
  5.     <init-param>  
  6.         <param-name>excludedPages</param-name>    
  7.         <param-value>  
  8.             /pages/noticeRule!editNotice.action,  
  9.             /pages/noticeRule!addNotices.action,  
  10.             /pages/noticeRule!templatePreview.action,  
  11.             /pages/filter!update.action,  
  12.             /pages/filter!save.action         
  13.         </param-value>  
  14.     </init-param>  
  15. </filter>  
  16. <filter-mapping>  
  17.     <filter-name>XSS</filter-name>  
  18.     <url-pattern>/*</url-pattern>  
  19. </filter-mapping>  



其中XssFilter爲自定義的class,該類必須實現Filter類,在XssFilter類中實現doFilter函數。將策略文件放到和pom.xml平級目錄下然後我們就開始編寫XssFilter類。

[java] view plain copy
  1. package net.wechance.bugfix;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.Filter;  
  6. import javax.servlet.FilterChain;  
  7. import javax.servlet.FilterConfig;  
  8. import javax.servlet.ServletException;  
  9. import javax.servlet.ServletRequest;  
  10. import javax.servlet.ServletResponse;  
  11. import javax.servlet.http.HttpServletRequest;  
  12.   
  13. import org.apache.commons.lang3.StringUtils;  
  14.   
  15.   
  16. /** 
  17.  * XSS過濾器 
  18.  * 用於過濾XSS 
  19.  * @author William 
  20.  * @since 2014-11-21 
  21.  */  
  22. public class XssFilter implements Filter {  
  23.       
  24.     /**  
  25.     * 需要排除的頁面  
  26.     */    
  27.     private String excludedPages;    
  28.         
  29.     private String[] excludedPageArray;   
  30.       
  31.     @SuppressWarnings("unused")  
  32.     private FilterConfig filterConfig;  
  33.   
  34.     public void destroy() {  
  35.         this.filterConfig = null;  
  36.     }  
  37.       
  38.     public void doFilter(ServletRequest request, ServletResponse response,  
  39.             FilterChain chain) throws IOException, ServletException {  
  40.           
  41.         boolean isExcludedPage = false;  
  42.           
  43.         HttpServletRequest request2 = (HttpServletRequest) request;  
  44.         String ctx_path = request2.getContextPath();  
  45.         String request_uri = request2.getRequestURI();  
  46.         String action = request_uri.substring(ctx_path.length());  
  47.           
  48.         //判斷是否在過濾url之外   
  49.         for (String page : excludedPageArray) {  
  50.             if (page.equals(action)) {  
  51.                 isExcludedPage = true;   
  52.                 break;  
  53.             }  
  54.         }  
  55.           
  56.         if (isExcludedPage) {  
  57.             chain.doFilter(request, response);  
  58.         } else {  
  59.             chain.doFilter(new RequestWrapper(request2), response);  
  60.         }  
  61.           
  62.     }  
  63.       
  64.     /** 
  65.      * 自定義過濾規則 
  66.      */  
  67.     public void init(FilterConfig filterConfig) throws ServletException {  
  68.         this.filterConfig = filterConfig;  
  69.         excludedPages = filterConfig.getInitParameter("excludedPages");    
  70.         if (StringUtils.isNotEmpty(excludedPages)) {  
  71.             excludedPageArray = excludedPages.replaceAll("[\\s]""").split(",");  
  72.         }  
  73.     }  
  74.       
  75.       
  76. }  



OK,我們需要重寫request,新建一個類RequestWrapper,繼承HttpServletRequestWrapper,我們需要重寫getParameterMap()方法,以及過濾非法html的方法xssClean()

[java] view plain copy
  1. package net.wechance.bugfix;  
  2.   
  3.   
  4. import java.io.InputStream;  
  5.   
  6.   
  7. import org.apache.commons.lang3.StringUtils;  
  8. import org.apache.log4j.Logger;  
  9.   
  10.   
  11. import org.owasp.validator.html.AntiSamy;  
  12. import org.owasp.validator.html.CleanResults;  
  13. import org.owasp.validator.html.Policy;  
  14. import org.owasp.validator.html.PolicyException;  
  15. import org.owasp.validator.html.ScanException;  
  16.   
  17.   
  18. /** 
  19.  * XSS清潔工 
  20.  * 用於過濾XSS 
  21.  * @author William 
  22.  * @since 2014-11-21 
  23.  */  
  24. public class XssClean {  
  25.   
  26.   
  27.     private static final Logger logger = Logger.getLogger(XssClean.class);  
  28.     private static Policy policy = null;  
  29.       
  30.     public static Policy getPolicy() throws PolicyException {  
  31.         if (policy == null) {  
  32.             InputStream policyFile = XssClean.class.getResourceAsStream("/antisamy-config.xml");  
  33.             policy = Policy.getInstance(policyFile);  
  34.         }  
  35.         return policy;  
  36.     }  
  37.       
  38.     public static String xssClean(String value) {  
  39.         if (StringUtils.isNotEmpty(value)) {  
  40.             AntiSamy antiSamy = new AntiSamy();  
  41.             try {  
  42.                 final CleanResults cr = antiSamy.scan(value, getPolicy());  
  43.                 //安全的HTML輸出  
  44.                 value = cr.getCleanHTML();  
  45.             } catch (ScanException e) {  
  46.                 logger.error("過濾XSS異常");  
  47.                 //e.printStackTrace();  
  48.             } catch (PolicyException e) {  
  49.                 logger.error("加載XSS規則文件異常: " + e.getMessage());  
  50.                 //e.printStackTrace();  
  51.             }  
  52.         }  
  53.         return value;  
  54.     }  
  55. }  

好了,到此爲止,我們的AntiSamy就成功添加到項目了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章