如何預防跨網站指令碼的安全性問題

文章翻譯 文章翻譯
文章編號: 252985 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

結論

如果輸入內容在傳入或傳出的過程中沒有經過驗證,動態產生的 HTML 頁面可能帶來安全性風險。惡意指令碼可能內嵌於送交至網頁的輸入內容中,讓瀏覽器將其視為來自信任的來源。這個問題稱為跨網站指令碼的安全性問題。本文將探討跨網站指令碼的安全性問題、造成的後果與預防措施。

其他相關資訊

問題

根本的問題在於,許多網頁會顯示未經驗證的輸入內容。如果輸入內容未經驗證,惡意指令碼就能內嵌至輸入內容中。如果伺服器端的指令碼接著顯示此未經驗證的輸入內容,指令碼就會在瀏覽器上執行,就像是由信任的網站所產生的指令碼一樣。

後果

如果輸入您動態網頁的內容未經驗證,您可能會遭遇下列問題:
  • 資料完整性受到破壞。
  • Cookie 可能被設定或讀取。
  • 使用者輸入內容可能被攔截。
  • 用戶端可能在信任來源的內容中執行惡意指令碼。
哪些網頁有這樣的風險?基本上,這項問題會影響到根據未經驗證的輸入內容建立動態頁面的程序。典型的例子包括下列兩種網頁:
  • 根據使用者輸入內容傳回結果頁面的搜尋引擎。
  • 將使用者帳戶儲存在資料庫、Cookie 等位置,之後再將使用者名稱寫下,傳送給用戶端的登入頁面。
  • 處理信用卡資訊的網頁表單。

預防措施

本節提供避免受到跨網站指令碼安全性攻擊的一些預防措施。請根據您本身的情況評估,判斷哪個方法最適合您。請特別注意,在所有的方法中,您要驗證的都是透過輸入內容接收到的資料,而不是您信任的指令碼。基本上,預防措施就是要遵循良好的編程原則,對要加入至常式的輸入內容執行例行性檢查。

下列清單列出了避免遭受跨網站指令碼攻擊的一般方法:
  • 對根據輸入參數產生的輸出內容編碼。
  • 篩選輸入參數中的特殊字元。
  • 在根據輸入參數產生的輸出內容中,篩選特殊字元。
當您篩選或編程時,必須為網頁指定字元集,確保您的篩選器確實檢查適當的特殊字元。插入您網頁的資料,應該篩選掉特殊字元集所認定的特殊位元組序列。ISO 8859-1 是常用的字元集之一,也是較早版本 HTML 和 HTTP 的預設設定。在變更這些參數時,您必須將當地語系化的問題納入考量。

在根據輸入參數產生的輸出內容中,針對特殊字元進行編碼

當您要將資料寫下成為 HTML 供輸出時,對透過輸入內容接收的資料進行編碼。對於在輸入時因為某些原因而未經驗證的資料,這個技術很有效。您可以藉由像 URLEncodeHTMLEncode 的技術,防止惡意指令碼執行。

下列程式碼片段示範如何由動態伺服器網頁 (ASP) 網頁使用 URLEncodeHTMLEncode
<%
      var BaseURL = http://www.mysite.com/search2.asp?searchagain=;
      Response.write("<a href=\"" + BaseUrl +
      Server.URLEncode(Request.QueryString("SearchString")) +
      "\">click-me</a>");
%>
<% Response.Write("Hello visitor <I>" +
      Server.HTMLEncode(Request.Form("UserName")) +
      "</I>");
%>
				
如果您對 HTML 和 URL 編碼,可能和篩選資料時一樣需要指定字碼頁。

請特別注意,呼叫要顯示的字串中的 HTMLEncode 時,會避免執行字串中的任何指令碼,因此能避免發生問題。

篩選輸入參數中的特殊字元

篩選輸入內容的運作方法,是由您的輸入內容中移除部分或所有特殊字元。特殊字元是讓指令碼能夠產生於 HTML 資料流中的字元,包括下列字元:
< > " ' % ; ) ( & + -
				
請注意,根據您個人情況的不同,您篩選的範圍可能包括特殊字元以外的其他字元或字串。

雖然篩選是有效的技術,但有些事項需要注意:
  • 某些輸入內容可能不適合使用篩選方式。例如,當您由 HTML 表單接收到 <TEXT> 的輸入內容時,可能應該選擇使用像編碼的方式 (請參閱下文)。
  • 部分篩選到的字元,可能實際上是伺服器端指令碼需要的輸入內容。
以下範例篩選器是以 JavaScript 撰寫,示範如何移除特殊字元:
function RemoveBad(strTemp) { 
    strTemp = strTemp.replace(/\<|\>|\"|\'|\%|\;|\(|\)|\&|\+|\-/g,""); 
    return strTemp;
} 
				
下列程式碼會先處理使用者輸入內容,再讓這些輸入內容儲存供日後使用。
<% Session("StoredPreference") = RemoveBad(Request.Cookies("UserColor"));
         var TempStr = RemoveBad(Request.QueryString("UserName"));				

在根據輸入參數產生的輸出內容中,篩選特殊字元

這個技術與篩選輸入內容相似,只差在您篩選的是寫出至用戶端的字元。這個技術雖然有效,但可能讓網頁在寫出 HTML 元素時發生問題。

例如,在寫出 <TABLE> 元素的頁面上,移除特殊字元的一般函式會刪除 < 和 > 字元,導致 <TABLE> 標籤損毀。因此,為了讓這個技術產生效用,您只能篩選傳入的資料,或者針對使用者先前輸入並儲存在資料庫中的資料進行篩選。

可能的惡意資料來源

雖然任何使用輸入內容動態產生 HTML 的頁面,都可能發生這個問題,但以下還是提供了一些可能的惡意資料來源,協助您抽檢可能的安全性風險:
  • 查詢字串
  • Cookie
  • 張貼的資料
  • URL 和 URL 的部分,例如 PATH_INFO
  • 以某些方式保存的擷取自使用者的資料 (如保存在資料庫中)

結論

總結以上所述,下列是處理跨網站指令碼安全性問題時要切記的關鍵:
  • 這項問題會影響到根據未經驗證的輸入內容產生動態頁面的程序。
  • 忽略對輸入資料執行例行性檢查,可能會受到無法預期的安全性問題牽連。這個問題可以透過良好的開發標準加以防範,例如對輸入內容進行驗證。
  • 您需要根據網站、網頁,甚至欄位評估解決方案,並採用適合的技術。

?考

如需詳細資訊,請參閱下列卡內基美隆大學 (Carnegie Mellon University) 的電腦危機處理中心 (Computer Emergency Response Team,CERT) 的報告文件:
http://www.cert.org/advisories/CA-2000-02.html
如需詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件:
253117 防範 Internet Explorer 和 Outlook Express 的跨網站指令碼安全性問題 (機器翻譯)
253119 如何檢視 ASP 程式碼中的 CSSI 弱點 (機器翻譯)
253120 如何檢視 Visual InterDev 所產生程式碼中的 CSSI 弱點 (機器翻譯)
253121 如何檢視 MTS/ASP 程式碼中的 CSSI 弱點 (機器翻譯)

屬性

文章編號: 252985 - 上次校閱: 2008年5月30日 - 版次: 3.3
這篇文章中的資訊適用於:
  • Microsoft Active Server Pages 2.0
  • Microsoft Active Server Pages 3.0
  • Microsoft Windows 2000 Server
關鍵字:?
kbcodesnippet kbcssi kbhowto kbsecurity KB252985
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com