跨站點腳本編制-XSS 描述及解決方法


  跨站點腳本編制可能是一個危險的安全性問題,在設計安全的基於 Web 的應用程序時應該考慮這一點。本文中,描述了這種問題的本質、它是如何起作用的,並概述了一些推薦的修正策略。

  當今的大多數網站都對 Web 頁面添加了動態內容,從而使用戶能獲得更愉快的體驗。動態內容是由某些服務器進程生成的內容,它可以根據用戶的設置和需要在提交時表現出不同的行為和產生不同的顯示。動態網站存在着一個稱為“跨站點腳本編制”(也稱為“XSS”)的威脅,而這是靜態網站所沒有的。

  “一個網頁可以包含由服務器生成的、並且由客戶機瀏覽器解釋的文本和 HTML 標記。只生成靜態頁面的網站能完全控制瀏覽器用戶如何解釋這些頁面。而生成動態頁面的網站不能完全控制客戶機如何解釋其輸出。問題的核心是,如果不可信的內容被引入到動態頁面中,則無論是網站還是客戶機都沒有足夠的信息識別這種情況的發生並采取保護措施。

  跨站點腳本編制正不斷受到攻擊者的廣泛青睞,因為在網站上很容易找到這種安全性問題。商業站點上每月都會發現跨站點腳本編制的攻擊,並且每月都會發布解釋這種威脅的報告。如果不加注意,則您網站的安全運行的能力以及您公司的聲譽都可能成為這些攻擊的犧牲品。

  跨站點腳本編制的威脅

  跨站點腳本編制將服務器應用程序置於危險之中,這些危險包括(但不限於)以下幾種情況:

  A 當用戶查看基於攻擊者提供的內容而動態生成的頁面時,他們會不知不覺地執行惡意腳本。

  B 在用戶的會話 cookie 失效之前,攻擊者就能接管用戶會話。

  C 攻擊者可以將用戶連接到攻擊者選擇的惡意服務器上。

  D 攻擊者誘導用戶訪問由攻擊者提供的 URL,從而導致在用戶的瀏覽器中執行攻擊者選擇的腳本或 HTML。通過使用這種技術,攻擊者可以使用訪問過此 URL 的用戶的特權來采取行動,諸如對底層 SQL 數據庫發出查詢並查看其結果,以及使用目標系統上已知的有問題的實現。

 發動攻擊

當攻擊者知道某一網站上的應用程序易受跨站點腳本編制攻擊后,他就可以規划攻擊。攻擊者最常用的技術是使用受害者的特權在受害者的系統上插入 JavaScript、VBScript、ActiveX、HTML 或 Flash 並執行。一旦激活了攻擊,就可能發生從截獲帳戶、更改用戶設置、竊取和篡改 cookie 到虛假廣告在內的任何事情。


樣本攻擊方案

以下方案用圖說明了一些比較典型的攻擊。但是,我們無法列出有關弱點的所有變體情況。要了解有關已記錄在案的攻擊,以及作為供應商或作為用戶如何自衛的更多信息,請參閱 參考資料一節。

借助惡意鏈接的腳本編制

在本方案中,攻擊者將一個專門精心制作的電子郵件消息發送給受害者,這個消息包含如下所示的惡意鏈接腳本:

<A HREF=http://legitimateSite.com/registration.cgi?clientprofile=<SCRIPT>malicious code</SCRIPT>>Click here</A>

當沒有對此產生懷疑的用戶點擊該鏈接時,URL 被發送到包含惡意代碼的 legitimateSite.com 。如果合法服務器將一個包含 clientprofile 值的頁面發回給用戶,則在客戶機 Web 瀏覽器上就會執行惡意代碼,如 圖 1 所示。


圖1 通過電子郵件攻擊
圖 2 的標題

竊取用戶cookie

如果網站的任一部分使用了 cookie,則從該網站的用戶處竊取這些 cookie 是有可能的。本方案中,攻擊者使包含惡意腳本的頁面成為易受攻擊站點的一部分。顯示該頁面時,惡意腳本就運行,它收集用戶的 cookie,並向攻擊者的網站發送包含收集到的 cookie 的請求。通過使用這種技術,攻擊者可以獲得諸如密碼、信用卡號以及用戶輸入的任意信息等敏感數據,如 圖 2 所示。


圖2 竊取cookie和截獲帳戶
竊取 Cookie 和截獲帳戶

發送未經授權的請求

在本方案中,當用戶執行郵件消息中的惡意鏈接時,就會不知不覺地執行攻擊者編寫的腳本。因為惡意腳本執行時所在的上下文看上去源自合法服務器,所以攻擊者對所檢索的文檔有完全的訪問權,並可以將包含在頁面中的數據發回他們自己的站點。如果嵌入的腳本代碼具有額外的與合法服務器交互的能力,並且交互時不會警告受害者,則攻擊者可以開發和利用合法 Web 服務器上不同頁面中張貼的那些數據,如 圖 3 所示。


圖3 發送未經授權的請求
發送未授權請求


避免攻擊

如上所述,當攻擊者能夠使合法 Web 服務器將一個包含攻擊者選擇的惡意腳本的頁面發送到受害用戶的 Web 瀏覽器時,就實現了跨站點腳本編制攻擊。然后攻擊者就可以使用源自合法 Web 服務器的合法腳本的特權運行惡意腳本。

既然我們知道了攻擊的基本知識,那么做些什么才能保護我們自己避免這一脆弱性呢?

通過確保動態生成的頁面不包含不期望的標記,網站開發人員可以防止他們的站點被濫用。

從 Web 用戶的角度而言,要降低因為這一脆弱性而遭受攻擊的風險,有兩種選擇。第一種選擇是在 Web 瀏覽器中禁用腳本編制語言,以及禁用支持 HTML 的電子郵件客戶機,這種選擇提供了最大程度的保護,但存在着禁用功能的副作用。第二種選擇是只執行主網站的鏈接進行查看,這將顯著降低用戶暴露給攻擊者的風險,同時仍能保留功能。

但是,在 Web 用戶可以采用的任何解決方案中,沒有一種是徹底的解決方案。最終,還是應當由 Web 頁面開發人員作出決定來修改他們的頁面以消除這幾類問題。通過適當過濾和驗證所接收的輸入以及適當編碼或過濾返回給用戶的輸出,可以實現這一點。

過濾

這種方法的基本原理是決不相信用戶輸入,並總是過濾 HTML 規范中定義的元字符(“特殊”字符)。對包括鏈接參數在內的每個輸入字段都驗證是否為腳本標記。當發現這樣的輸入時,根據上下文來拒絕它,這樣可以防止向用戶提供惡意的 HTML。

這種方法所帶來的復雜性是許多 Web 瀏覽器都會嘗試糾正 HTML 中常見的錯誤。其結果是,依照規范,當有些字符不是特殊字符時,他們有時也會將這些字符視為特殊字符。因此,要注意可能保證把額外字符包括到特殊字符列表中的個別情況,這一點很重要。Web 開發人員必須檢查他們的應用程序,並確定哪些字符會影響他們的 Web 應用程序。

對輸入端進行過濾的效率比較低,因為通過除了 HTTP 以外的其它方法也可以將動態內容輸入到網站數據庫中。本例中,Web 服務器可能從未將這些數據視為數據輸入過程的一部分,因此這些數據元素仍然可能是受污染的。另外,建議就在數據作為動態頁面的一部分呈現之前,將過濾作為數據輸出過程的一部分來完成。正確執行后,這種方法確保過濾了所有動態內容。

編碼

當 Web 服務器充分確保了對生成的頁面進行了正確編碼以防止腳本的無意執行時,可以避免跨站點腳本編制的攻擊。

ISO-8859-1 規范中的每個字符都可以使用其數字項值進行編碼。服務器端的編碼是一個過程,其中所有動態內容都將經過一個編碼函數,這時,腳本編制標記將被替代為所選擇的字符集中的代碼。

一般而言,推薦進行編碼,因為它不要求您決定什么樣的字符可以合法地輸入,而什么樣的字符需要通過編碼函數的檢查。遺憾的是,對所有不可信數據編碼是資源密集型的工作,而且可能對某些 Web 服務器產生性能方面的影響。


哪種策略適合我?

基於 CGI 的 Web 應用程序或支持瀏覽器中字段編輯檢查的應用程序很可能適合於過濾策略,通過將現有的字段編輯檢查擴展至包括檢查跨站點腳本編制的弱點即可。請注意,雖然瀏覽器端的字段編輯檢查節省了與服務器通信的幾個來回,但它適用於誠實的用戶,而且需要完整的代碼遍歷以保證檢查了所有的輸入字段來滿足修正建議的要求。但是,內部設計有服務器端驗證的 Web 應用程序可以選擇適應兩種策略中的任一種,或同時適應這兩種策略。

要使過濾策略正確工作,Web 開發人員需要確保的是,依照其應用程序的需要,過濾用的元字符列表是最新的。相反,編碼策略不需要進行上述維護工作,而且它對現有應用程序代碼以及應用程序功能的影響也較小。基於這些原因,看來編碼策略是受歡迎的實現選擇。下一節將描述樣本編碼實現。


樣本編碼

對 Web 服務器而言,確保正確編碼所生成的頁面的簡單而又有效的方法是:將動態內容中的每個字符都傳遞通過一個編碼函數,在該函數中,動態內容中的腳本編制標記被替代為所選定的字符集中的代碼。這個任務最適合於定制標記庫。

定制標簽庫的基礎知識

定制標記庫由一個或多個 Java 語言類(稱為標記處理程序)以及 XML 標記庫描述文件(TLD)組成,后者描述新的標記名和那些標記的有效屬性。標記處理程序和 TLD 確定在請求時,從 JSP 頁面內如何解釋和處理這些標記及其屬性和主體。在封裝復雜操作時,定制標記庫提供了一種比 Java bean 更靈活的體系結構。


定制的合適標簽庫

除了將我們的定制標記庫命名為 XSS 之外,還有什么更好的叫法嗎?標記庫是插入到 servlet 容器的軟件組件。servlet 容器創建標記處理程序,對它們初始化並依次調用 doStartTag()doEndTag()release() 方法。

通過這些交互,我們的 XSS 定制標記庫就能應用“定制”操作,這種操作編碼在 JSP 頁面上找到的動態數據。實現定制標記很簡單,其步驟如下所示:

  • 創建一個描述標記的標記庫描述符( .tld )。
  • taglib 偽指令添加到使用這些標記的 JSP 文件中。
  • 實現繼承 TagSupport 和覆蓋 doStartTag()doEndTag() 方法的標記處理程序。

 

 

 

TLD(標記庫描述符)

標記庫描述符是一個 XML 文件,其元素描述了特殊的標記庫。 清單 1 顯示了我們的 XSS 定制標記庫的 tld 文件。標記元素定義了 encode 操作,包括屬性 propertytagclass 元素定義標記處理程序類 EncodeTag


清單 1. xss.tld 文件

<?xml version="1.0" encoding="UTF-8"?>
 DOCTYPE taglib
   PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
   "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

<taglib>
     <tlibversion>1.0</tlibversion>
     <jspversion>1.1</jspversion>
     <tag>
        <name>encode</name>
        <tagclass>dw.demo.xss.EncodeTag</tagclass>
        <bodycontent>empty</bodycontent>
        <attribute>
            <name>property</name>
            <required>true</required>
        </attribute>
     </tag>
<taglib>

 

taglib 偽指令

taglib 偽指令識別標記庫描述符,並定義使后繼標記與庫相關聯的標記前綴。在使用 XSS 定制標記庫的 JSP 中出現的樣本 taglib 偽指令如下所示:

   <%@ taglib uri="/WEB-INF/tlds/xss.tld" prefix="xss" %>
 

 

 

標記處理程序是 Web 容器中的對象,在執行 JSP 頁面時它幫助對操作求值。 EncodeTag 類是用於編碼操作的標記處理程序。它的 doStartTag 方法將動態內容編碼為 ISO-8859-1 字符集,該方法顯示在 清單 2中。


清單2 編碼動態內容

 public int doStartTag() throws JspException {

     StringBuffer sbuf = new StringBuffer();

     char[] chars = property.toCharArray();
     for (int i = 0; i < chars.length; i++) {
          sbuf.append("&#" + (int) chars[i]);
     }

     try{
          pageContext.getOut().print(sbuf.toString());
     } catch (IOException ex) {
          throw new JspException(ex.getMessage());
     }

     return SKIP_BODY;
 }

 


部署

XSS 定制標記庫是 Web 應用程序的一部分,它作為附加文件打包到 Web 應用程序的 WAR 文件中,如下所示:

  • WEB-INF/lib/encodetaglib.jar
  • WEB-INF/tlds/xss.tld

 

 

 


應用

以下方案說明了如何使用定制標記庫。假設有一個接收文章的虛擬網站,其中有一個評論您所訂閱文章的頁面。動態內容,即打算提供給您的文章條目,是在 JSP 文件內使用 <%= expression %> 語法准備的。

讓我們假設攻擊者成功地將一個包含惡意腳本的頁面填入到訂閱成員使用的網站上。這個成功攻擊的效果,就是當在用戶瀏覽器上執行該頁面時,會顯示一個彈出窗口,如 圖 4 中所示。


圖4 編碼前
編碼前

在下一個方案中,這個虛擬網站確保生成的頁面是通過使用 XSS 定制標記庫正確編碼的,並且能避免攻擊。不可信的數據被保留下來用於在瀏覽器中可視查看,如 圖 5 所示。


圖5 編碼后
編碼后


結語

本文中,我們討論了攻擊者如何使用跨站點腳本編制作為對網站發動攻擊的技術。我們還演示了當網站使用簡單的定制標記庫正確編碼動態內容時,可以消除大多數攻擊。可以“按現狀”使用 XSS 定制標記庫,或更為有效地更改該定制標記庫使之適合您的 Web 應用程序需要,保護您的 Web 應用程序避免受到這種新出現的威脅。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM