ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 善用 ASP.NET 內建功能來擊退網路攻擊

善用 ASP.NET 內建功能來擊退網路攻擊

原创 Linux操作系统 作者:Kenniu 时间:2019-07-08 12:27:06 0 删除 编辑
 

作者:Dino Esposito
Wintellect

2005 年 1 月

適用於:
   Microsoft ASP.NET 1.x
   Microsoft ASP.NET 2.0

摘要: Dino 重點說明最常見的 Web 攻擊類型,並解說 Web 開發人員應如何使用 ASP.NET 內建功能來加強安全性。

(本文含有連至英文網站的連結,列印共 13 頁)

目錄

ASP.NET 開發人員守則 威脅成因
ViewStateUserKey
Cookie 與驗證
工作階段劫奪
EnableViewStateMac
ValidateRequest
透視資料庫
隱藏欄位
E-mails 與垃圾郵件
總結
相關資源

ASP.NET 開發人員守則

既然您已在閱讀本文,也就不必他人的叮嚀,告訴您日趨重要的 Web 應用程式安全性。您可能想要知道一些實用的技巧,來運用在 ASP.NET 應用程式的安全性。不幸的是,沒有一個開發平台在你使用之後,能保證讓您撰寫百分之百安全的程式碼,包括 ASP.NET 在內,若有人說可以,那純屬虛構。但我有個好消息,單就 ASP.NET 而言,它的 1.1 版還有即將推出的 2.0 版都整合了許多內建防禦機制供您使用。

單單應用這些功能是無法保護 Web 應用程式,對抗可能或可預測的攻擊,不過,若與其他的防禦技術與安全性策略一起搭用,ASP.NET 內建功能即可造就一個有力的工具包,進而確保應用程式能在安全的環境下運作。

Web 安全性的成因有很多,它會受到各種策略的影響,不僅僅是單一應用程式,資料庫管理、網路設定以及科技強迫推銷與網路詐騙等等也會所有影響。

本文目的是在解說 ASP.NET 開發人員所應遵守的事宜,以採用適度的安全防護標準,畢竟安全性就是需要高警覺性,不能有任何鬆懈,不讓駭客有可趁之機。

現在就讓我們來看看,ASP.NET 的功能如何能簡化這個工作。

威脅成因

我整理出 [表 1],重點說明常見的 Web 攻擊類型與其利用的應用程式弱點。

攻擊類別 手法
跨站台的指令碼處理 (XSS) 攻擊 回應至網頁的不受信任使用者輸入
SQL 資料隱碼攻擊 以使用者輸入串連形成 SQL 命令碼
工作階段劫奪 工作階段識別碼推測與工作階段識別碼 Cookie 竊取
滑鼠點擊攻擊 以指令碼傳送的不明 HTTP 張貼
Hidden field tampering 未檢查 (和受信任的) 隱藏欄位內具有敏感性資料

[表 1] 常見的 Web 攻擊

上述清單裡,主要的事實是什麼?我個人認為可歸類成下類三點:

  • 只要將任一類型的使用者輸入插入到瀏覽器標記,就有可能公開自己而受到程式碼植入的攻擊 (各種 SQL 資料隱碼和 XSS 的攻擊)。
  • 資料庫存取必須完全安全,換言之,幫帳戶採用最少的權限組,並利用角色來區分各個使用者的責任。
  • 敏感性資料絕對不可透過網路傳送 (尤其是純文字格式),應安全地儲存在伺服器上。

有趣的是,上面所提到的三點是 Web 安全性截然不同三個領域,但唯有搭用這些技巧,方能建立穩固的防護,使應用程式不受侵犯。Web 安全性的主控方法有三:

  • 程式碼運用:資料驗證、類型與緩衝時間長度檢查、反侵犯措施
  • 資料存取策略:利用角色來確保安全性最弱的帳戶,使用預存程序或至少參數型命令。
  • 有效地儲存與管理:勿將重要資料以網路寄給客戶,使用雜湊碼來偵測惡意操作、驗證使用者並保護識別身分、套用嚴格的密碼原則

如前所述,開發人員、架構者與管理員要攜手合作,才有安全的應用程式,千萬不要認為您一人就可以包辦。

在撰寫 ASP.NET 應用程式時,您不是孤零零一個人,只憑自己的大腦、技巧和輸入程式碼的雙手來奮戰駭客軍團。ASP.NET 1.1 和更新的版本能提供您一些新的功能,自動就上述某些威脅形成一面護牆。現在就讓我們看看吧。

ViewStateUserKey

ViewStateUserKey 是 ASP.NET 1.1 引進的,它是 Page 類別的一個字串屬性,不過真正懂得這個屬性的開發人員少之又少。原因為何?我們來看一下相關文件的內容就知道。

Assigns an identifier to an individual user in the view state variable associated with the current page (將識項指派到與目前頁面相關之檢視狀態變數裡的單一使用者)

除了又臭又長的敘述風格之外,語句還算清楚,可是,這句話真的解釋了該屬性的目的為何嗎?要想瞭解 ViewStateUserKey 的真面目,必須繼續往下讀,直到 Remarks (附註) 那一段才會真相大白。

這個屬性可用來防止滑鼠點擊式攻擊,提供它種輸入,建立能防禦檢視狀態免受侵入的雜湊值。也就是說,駭客若使用用戶端檢視狀態來進行惡意張貼,使用 ViewStateUserKey 可大幅提高網站的防禦能力。此屬性可指派至任一非空白字串,但最好是工作階段識別碼或使用者識別碼。接下來,我們來談談滑鼠點擊式攻擊,藉此瞭解這個屬性的重要性。

滑鼠點擊式攻擊是在網站上張貼惡意 HTTP 表單,它之所以稱為「滑鼠點擊式」,是因為這種攻擊要不知情的受害者按下電子郵件裡或熱門討論區裡的引誘連結,才會發生攻擊。按下連結後,使用者不知不覺地觸發一個遠端程序,將惡意的

提交到某個網站。誠實招來,您從未因為好奇,然後按下類似 百萬大獎拿不完 這種連結嗎?顯然的,對您而言並沒發生過什麼壞事情,我們只能這樣假設,但是您能保證其他 Web 設群一樣安然無恙嗎?這就難說了。

滑鼠點擊式攻擊要有下列背景條件才會成功:

  • 攻擊者必須對不安全的網站瞭若指掌。他們之所以可能瞭解這些網站,很可能是認真研究過裡面的檔案,或者他們是「內賊」(舉例而言,被革職或是不誠實的員工)。也因此,這種攻擊破壞性十分強。
  • 網站必定使用 Cookie (永續的 Cookie 更好) 來進行單一登入,而攻擊者應該要有有效的驗證 Cookie。
  • 網站的某些使用者在執行敏感交易。
  • 攻擊者必定具有目標網頁的存取權。

前面已提過,這種攻擊的方法需要將惡意的 HTTP 表單提交至需要一個表單的網頁,且該網頁需要所發佈的資訊來處理一些敏感作業,而攻擊者熟知每個會用到的欄位,並能提供假的值來達成他的目標。這種通常是目標攻擊,使用的是三角架構 (駭客引誘受害者在駭客的網站上按下連結,進而發佈惡意程式碼給第三方網站),所以很難追蹤攻擊者 (請參閱 [圖 1])。

ms972969.securitybarriers01(zh-tw,MSDN.10).gif

[圖 1] 滑鼠點擊式攻擊

為何要牽扯到沒有戒心的受害者?因為這樣做的話,伺服器記錄檔內的資料就會顯示,惡意要求是來自點擊滑鼠的 IP 位址。前面提過,這種攻擊與 XSS 那種「典型」的攻擊相較之下,並不常見,但是它的本質使它的破壞性十分強烈。那防禦辦法為何?下面會從 ASP.NET 的角度來深究這種攻擊的結構。

除非將動作編碼到 Page_Load 事件裡,否則 ASP.NET 網頁並不會在回傳事件之外執行敏感程式碼。若要有回傳事件,檢視狀態欄位是必備的。請記住,根據 _VIEWSTATE 輸入欄位的存在與否,ASP.NET 會檢查要求的回傳狀態,再依結果設定 IsPostBack。因此,舉凡想寄送虛構要求至 ASP.NET 網頁的人,皆必須提供有效的檢視狀態欄位。

若想順利進行滑鼠點擊式攻擊,駭客必須要能存取目標網頁,進入網頁後,有遠見的駭客會在其本機上儲存該網頁,如此一來,他就能夠存取 _VIEWSTATE 欄位,然後利用它建立出一個具有舊有檢視狀態的要求,並且把有害的值放在其他欄位中。問題是,這樣會成功嗎?

當然會。假若駭客能提供有效的驗證 Cookie,他就能進入系統,而該要求會被正常地處理。伺服器上根本不會檢查檢視狀態的內容 (如果 EnableViewStataMac 處於關閉狀態),頂多會看看他是否被竄改。依照預設,檢視狀態裡並無任何會將內容和特定使用者相結合的東西。駭客能輕鬆地重複使用他所得到的檢視狀態,合法進入所要的網頁,借其他使用者之名建立假的要求。此時,ViewStateUserKey 就派的上用場。

如果選擇正確,這個屬性會將使用者特定資訊加入到檢視狀態。一旦要求受到處理時,ASP.NET 會從該檢視狀態裡擷取金鑰,將它與正在執行的網頁裡的 ViewStateUserKey 相比對。如果兩者吻合,則表示該要求合法,反之,就會拋出例外。但是此屬性的有效值究竟為何?

ViewStateUserKey 設定為常數字串 (每個使用者都有同樣的值) 就等於沒有設定值一樣。您必須將它設為會依照使用者而所有差異的值,例如,使用者識別碼或是工作階段識別碼 (這個最好)。有鑒於一些技術與社會問題,工作階段識別碼不可預測,會逾時且因使用者而異,所以是最佳選擇。

您應該將下面程式碼放置於所有網頁裡:

void Page_Init (object sender, EventArgs e) {
   ViewStateUserKey = Session.SessionID;
   :
}

若您將上述程式碼 bolt 在 Page 衍生類別的 OnInit 虛擬方法裡,則只要撰寫一次即可 (請注意,您必須在 Page.Init 事件裡設定此屬性)。

protected override OnInit(EventArgs e) {
   base.OnInit(e); 
   ViewStateUserKey = Session.SessionID;
}

總體而言,使用基底網頁類別有益無害,詳細原因請參閱我另一篇文章:Build Your ASP.NET Pages on a Richer Bedrock。若想進一步瞭解滑鼠點擊式攻擊者的技倆,aspnetpro.com 網站上也有一篇十分好的文章供您參考。

Cookie 與驗證

Cookie 之所以存在,是因為它們有助開發成員成就其目的。Cookie 就好像是瀏覽器和伺服器之間的永續連結。對使用單一登入的應用程式而言,竊取到的 Cookie 正是攻擊者的得力助手,尤其是要進行滑鼠點擊式攻擊的攻擊者。

要想使用 Cookie,您不須明確地以程式設計的方式來建立或讀取它們。若您使用工作階段狀態或實作表單驗證,只要隱含式地使用就可以。沒錯,ASP.NET 支援無 Cookie 的工作階段狀態,而 ASP.NET 2.0 也引進無 Cookie 的表單驗證,理論上,您可以使用這些功能,而不採用任何 Cookie。我並不是鼓勵您不要使用 Cookie,因為這種情況下,可能會帶來比原本問題還嚴重的問題。其實,無 Cookie 的工作階段會把工作階段識別碼內嵌到 URL,這樣一來,所有的人都會看到工作階段識別碼了。

使用 Cookie 究竟會有哪些潛在問題?Cookie 可能會被盜竊 (換言之,被複製到駭客的機器上) 然後被毒化 (填入惡意資料),這些都是攻擊前的熱身動作。若 Cookie 被偷竊,驗證 Cookie 會「驗證」借用您名義連入到應用程式的外部使用者 (並使用受保護之網頁),讓駭客快樂地略過驗證程序,利用角色和安全性設定放肆地進行受害者可以進行的事情。正因為這個考量,驗證 Cookie 的壽命通常很短,只有半個小時 (請注意,即使伺服器工作階段需要更長的時間,Cookie 仍會過期)。在竊取的情況下,駭客只有半小時的時間可以進行攻擊。

這個時間可以延長,使用者就不必一次再一次地登入,但是要記得,這可能會帶給您一些風險。無論如何,還是盡量避免使用 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 也會用來擷取某使用者的工作階段狀態。工作階段識別碼會儲存到與要求一起傳送的 Cookie 中,也會儲存在瀏覽器所在的機器上。再說一次,如果工作階段 Cookie 被竊,駭客就可用它進行系統,存取他人的工作階段狀態。不用我說您也知道,只要指定的工作階段在作用中 (通常是 20 分鐘),這種情況就可能發生。透過欺騙工作階段狀態所進行的攻擊,又稱為 工作階段劫奪。有關工作階段劫奪的詳細資訊,請閱讀 Theft On The Web:Prevent Session Hijacking

這種攻擊所帶來的危險有多大?這很難說,要視網站的目的還有網頁的設計 (這很重要) 而定。舉例而言,假如您已取得他人的工作階段 Cookie,然後將它附在網站上一個網頁的某要求中。您載入網頁,然後瀏覽一般使用者介面。您無法在網頁裡插入任何程式碼,也無法改動網頁,不過現在可使用他人的工作階段狀態來執行此網頁。這好像不算壞,但是只要工作階段內資訊敏感且重要,這就夠駭客使用了。我再叮嚀一次,駭客不能偷窺工作階段儲存內容,但儲存在裡面的內容就好像是駭客自己合法輸入的,而駭客可以放肆地使用。舉例而言,某電子商務應用程式讓使用者可以一邊瀏覽且一邊加入欲購物品到購物車中。

  • 案例 1: 購物車的內容會被儲存到工作階段狀態。不過在結帳時,使用者被要求透過安全的 SSL 連線來確認、輸入付款資料。在這種情況下,駭客進入使用者的工作階段狀態後,能得到的只是受害者的購物喜好,工作階段劫奪並無造成大害,唯一的風險是機密被洩漏。
  • 案例二:此電子商務應用程式會處理每位已註冊使用者的個人資料,並將其儲存在工作階段狀態中。糟糕,個人資料內 (可能) 含有信用卡的資訊。為什麼把使用者個人資料細節儲存到工作階段中?此應用程式的目的之一,可能就是要為使用者省去每次都得輸入自己信用卡和銀行資訊的麻煩。結帳時,應用程式將使用者帶到預先填妥欄位的網頁。想也知道,其中一個欄位是從工作階段狀態裡取出的信用卡卡號資訊。您能猜出結果了吧!

應用程式的網頁設計是防範工作階段劫奪攻擊的主要方法。但還有兩個未解答的問題。第一,如何避免 Cookie 被竊取。第二,ASP.NET 能如何偵測、封鎖劫奪?

ASP.NET 工作階段 Cookie 十分單純,僅限於包含單一工作階段識別碼字串。ASP.NET Runtime 從 Cookie 中擷取工作階段識別碼,檢查它是否與使用中的工作階段符合。若識別碼是有效的,ASP.NET 會連結到對應的工作階段,然後繼續後續動作。對已竊取或是能猜出有效工作階段識別碼的駭客而言,這個行為對他們相當有利。

XSS、攔截式攻擊還有暴力進入用戶端電腦等攻擊法,都會取得有效的 Cookie。要想防止竊取,您應該運用安全最佳實行原則來防範 XSS 以及所有它種攻擊。

要預防他人推測出工作階段識別碼不如不要高估您的技巧。工作階段識別碼推測需要熟知如何預測有效的工作階段識別碼字串。就 ASP.NET 所用的演算法而言 (15 個隨機數字對應到 URL 啟用字元),您能猜出有效識別碼的機會好比海底撈針。我實在想不出任何您需要將預設工作階段識別碼產生器換成自己想要之產生器的理由,取代後,多半的情況下只是有利於攻擊者而已。

工作階段劫奪最糟糕的是,一旦 Cookie 被竊或被推測出來,ASP.NET 就無法偵測出 Cookie 被盜取使用。原因如前所述,ASP.NET 只進行識別碼檢查與 Cookie 原始位置核對。

我有位在 Wintellect 工作的好友 Jeff Prosise,他在 MSDN Magazine 刊登一篇有關工作階段劫奪的好文章,雖然該文章的結論可能不太樂觀:「建立堅固安全的防禦來抵擋靠竊取和推測工作階段識別碼進行攻擊的駭客,幾乎是不可能的事..」不過他開發的程式碼裡卻提供一個能讓安全防護再上一層樓的秘訣。Jeff 建立了 HTTP 模組,監視工作階段識別碼 Cookie 送進的要求還有送出的回應。模組內在送出的工作階段識別碼裡附加一個雜湊碼,如此一來,攻擊者就很難在重複使用該 Cookie。詳細資料,請參閱這裡的文章

EnableViewStateMac

檢視狀態是用來保存同個網頁兩個連續要求的控制項狀態。它的預設值是 Base64 編碼,並具有雜湊值,目的是要防止被竄改。若您不變更預設的網頁設定,檢視狀態受竄改的風險相當低。若攻擊者修改檢視狀態,或甚至利用正確的演算法進行重建,ASP.NET 仍會識破,然後拋出例外。遭受竄改的檢視狀態並不一定有害 (不過伺服器控制項狀態會受更動),可是有可能成為嚴重感染的途徑。因此,請勿 移除預設安排的電腦驗證碼 (MAC) 交叉檢查,這一點十分重要。(請參閱 [圖 2])。

ms972969.securitybarriers02(zh-tw,MSDN.10).gif

[圖 2] EnableViewStateMac 啟用時檢視狀態能免於竄改的原因

MAC 檢查啟用時 (預設為啟用),序列化的檢視狀態會內附加一個雜湊值,此值是來自伺服器端的值還有檢視狀態使用者金鑰 (若有的話)。檢視狀態被貼回去時,雜湊值會被重新計算 (以新產生的伺服器端值去計算),然後與所儲存的值相比較。如果兩者吻合,則該要求則受允許,反之,就會拋出例外。因此即使駭客有能力找出或是重建檢視狀態,他還必須知道伺服器端所儲存的值,才能推算出有效的雜湊值。尤其是 machine.config 的 <machineKey> 項目裡面參照的機器碼。

預設的情況下, 項目是自動生成的,而這個值儲存在 Windows 的 [本機安全授權] (LSA)。只有在 Web farms 的情況下,由於所有機器的檢視狀態的機器碼必須一樣,您才要在 machine.config 檔案裡將它指定為純文字。

檢視狀態 MAC 檢查是透過 @Page 指示詞的 EnableViewStateMac 屬性來控制的,前面提過,它的預設值是 True。請勿停用此控制,否則檢視狀態很容易被竄改,而您很可能遭到滑鼠點擊式攻擊。

ValidateRequest

跨站台指令碼 (XSS) 攻擊源於 1999 年左右,具有多年經驗的網站開發人員對跨站台指令碼 (XSS) 攻擊肯定一點都不陌生。簡單的說,XSS 會探索程式碼的漏洞,用它將駭客的可執行程式碼引進到其他使用者的瀏覽器工作階段。程式碼執行後會插入可執行不同動作的程式碼,例如,複製一份 Cookie 到駭客所控制的網站;監視使用者的網站工作階段並轉寄資料;以錯誤資訊修改入侵網站的行為與外觀,甚至將它變成持續性的,當使用者下次再回到該網頁時,詐欺程式碼會再度執行。若想進一步瞭解 XSS 攻擊,請參閱 TechNet 文章:Cross-site Scripting Overview

哪些程式碼漏洞會遭致 XSS 攻擊?

XSS 是利用會動態產生 HTML 網頁且不驗證回應到網頁之輸入的 Web 應用程式。這裡對 輸入 的定義是查詢字串的內容、Cookie 以及表單欄位。若此內容不受例行性檢查就放到網路上,很可能被駭客用來在用戶端瀏覽器上執行惡意指令碼 (畢竟,之前提到的滑鼠點擊式攻擊屬於 XSS 的變種)。典型的 XSS 攻擊牽涉到不知情的使用者按下內嵌有逸出指令碼的引誘連結,之後詐欺程式碼會送到易受攻擊的網頁,因為那些網頁完全信任程式碼,不驗證就輸出內容。以下是可能發生的例子:

使用者按下一個看似安全的連結,結果竟進入易受攻擊的網頁,裡面具有的某個指令碼程式會取得使用者機器上所有的 Cookie,然後將它們傳送到駭客的網頁。

要注意的是,不只有廠商才會面臨 XSS 的問題,且 XSS 並不一定只利用 Internet Explorer 的漏洞,市面上所有 Web 伺服器和瀏覽器都可能受到攻擊。更重要的是,並沒有一個補充程式能解決問題。您可以預防網頁受到 XSS 攻擊,方法是採用特定措施以及健全的編程原則。此外,您也須意識到,這種駭客攻擊並不端賴使用者按下連結的動作。

要防禦 XSS 攻擊,您首先要決定輸入的有效性,並能拒絕無效之輸入。有關遏阻 XSS 攻擊的詳細檢查清單,請閱讀 Microsoft 書籍:《Writing Secure Code》,作者是 Michael Howard 和 David LeBlanc,我尤其建議您仔細閱讀第 13 章。

阻斷狡猾的 XSS 攻擊之主要方法,是在您的輸入 (任何種類的輸入資料) 裡加上周全又堅固的驗證層。舉例而言,在某些情況下,即使是無害的色彩,例如,RGB triplet,也可能把未受控制的指令碼直接引進網頁。

在 ASP.NET 1.1 中,@Page 指示詞的 ValidateRequest 屬性啟用時,它會檢查使用者是否利用查詢字串、Cookie 或表單欄位,寄送可能具危害性的 HTML 標記。如果偵測到,即會拋出例外,請求中止。依照預設,該屬性是啟用的,您無須採取任何動作就已受到保護。如果您想讓 HTML 標記傳遞,則要主動停用它。

<%@ Page ValidateRequest="false" %>

ValidateRequest不是 萬靈丹,無法用它取代有效率的驗證層。這個連結所提供的文章含有豐富的資訊,您不妨仔細閱讀,瞭解其運作方式。基本上,它套用一個規則運算式,來識別一些可能有害的序列。

注意 ValidateRequest 的功能最開始的時後有些缺陷,您需要安裝補充程式才能運作順暢。這個重要的資訊常常被忽略,我自己就很訝異我其中一台電腦仍未安裝補充程式,您不妨也檢查看看吧!

實在是沒有要停用 ValidateRequest 的原因,您是可以停用它,不過最好要有充分的理由,像是使用者要能將 HTML 貼回網站,以擁有更好的格式選擇。在這種情況下,您應該限制允許的 HTML 標籤數 (



),然後撰寫規則運算式,以確保其他的標籤不會被允許或接受。

下面提供幾個有助保護 ASP.NET 應用程式不受 XSS 攻擊的絕招:

  • 使用 HttpUtility.HtmlEncode 將危險符號轉換成其 HTML 表示。
  • 使用雙引號,不要用單引號,因為 HTML 編碼僅逸出雙引號。
  • 強制字碼頁限制可使用的字元數。

總之,使用 ValidateRequest 屬性是沒錯,可是不要懶,全都依靠它。建議您花點時間深入瞭解 XSS 攻擊等的安全性威脅,並以「使用者輸入是有害無益」為出發點規劃防禦策略。

透視資料庫

SQL 資料隱碼攻擊是另一種眾所皆知的攻擊方式,它會危害使用未過濾的使用者輸入,來建立資料庫命令碼。如果應用程式利用使用者在某表單欄位內輸入的內容,來建立一個 SQL 命令碼字串,惡意使用者只要存取該網頁,輸入不正當的參數,就可修改查詢的本質。有關更多 SQL 資料隱碼攻擊的資訊,請進入這裡

防止 SQL 資料隱碼攻擊的方法很多,以下是最常見的技巧。

  • 所有使用者輸入的類型皆正確並遵守預期的模式 (郵遞區號、身分正號碼、電子郵件地址)。若您預期接到來自文字塊的某個號碼,而使用者輸入的內容無法轉換成號碼,則須將其封鎖。
  • 使用參數化查詢或預存程序 (較佳)。
  • 使用 SQL Server 權限來限制每個使用者可進行的資料庫作業。舉例而言,您可停用 xp_cmdshell 或將其限制只有管理員可以使用。

若您使用預存程序,即可大幅度減少受攻擊的介面。事實上,有了預存程序,您不需要動態地撰寫 SQL 字串。除此,所有參數都會依指定的型別在 SQL Server 上受驗證。雖然此舉並無法提供百分之百安全性,但與驗證搭用,即可再強化安全性。

更重要的是,如果作業具有損害性,像是拖曳表格,您應只讓受驗證的使用者能執行。不過這需要謹慎地設計應用程式的中介層。有一個好方法,就是針對角色下手,而好處不只是能鞏固安全性。將使用者分類成各種角色,並以最少的權限集合依角色定義帳戶。

Wintellect 網站幾個星期前受到高超的 SQL 資料隱碼攻擊,駭客試圖要建立 FTP 指令碼,然後啟用該指令碼下載一個可執行檔。他攻擊失敗,可能是我們運氣好,也可能我們使用嚴謹的輸入驗證,搭用預存程序,再加上我們設定了 SQL 伺服器權限。

總之,遵循下列守則,能避免遭受 SQL 資料隱碼的攻擊:

  • 使用最少的權限集合,不以 sa 執行程式碼。
  • 限制內建預存程序的存取權。
  • 採用 SQL 參數化查詢。
  • 不透過字串串連來建置陳述式,不回應資料庫錯誤。

隱藏欄位

在傳統 ASP 裡,要保存要求間的資料,唯一的方法是使用隱藏欄位。您要在下一個要求擷取的資料,都封裝到一個隱藏的 欄位,而且是雙向的。但如果欄位內儲存的值在用戶端遭到修改,此時要怎麼辦?如果再加上是純文字,伺服器端環境根本不可能知道。網頁以及單獨控制項所用的 ASP.NET ViewState 屬性有兩個功能,第一,ViewState 是保存跨要求的方法,第二,ViewState 允許您將自訂值儲存在受保護且防止竄改的隱藏欄位中。

如 [圖 2] 所示,檢視狀態被附加了一個雜湊值,能檢查每個要求,進而能偵測竄改。在 ASP.NET 中,除了例外的情況下,實在不需要使用到隱藏欄位。檢視狀態能提供同樣的效果,而且更安全。前面已經說過,將像是價錢或信用卡資訊等敏感值以純文字儲存,就等於是敞開大門歡迎駭客來襲,但即使是這種不妥當的方式,檢視狀態的資料保護機制仍可以減緩危險性。然而,要切記在心的是,檢視狀態能防範竄改,卻無法保證機密性,除非您進行加密,因此,將信用卡資料儲存在檢視狀態儲就是不安全。

何時使用 ASP.NET 隱藏欄位才算安全?答案是,當您在建置需要將資料傳送回伺服器的自訂控制項時,舉例而言,您建立新的 DataGrid 控制項,能支援欄位的重新排序。您需要在回傳時,將新的順序傳回到在伺服器。若這些資訊不儲存在隱藏欄位裡,要存在哪呢?

假若隱藏欄位是讀取/寫入的欄位,也就是說,用戶端應該會進行寫入作業,則您對駭客的襲擊也無能為力了。您可試看看雜湊值或是對文字進行加密,但還是可能受到駭客的攻擊。最好的方法,是在隱藏欄位內存放無害的資訊。

話又說回來,其實有個資訊值得您瞭解,就是 ASP.NET 能公開一個類別,它可用於任何序列化物件的編碼與雜湊。此類別是 LosFormatterViewState 實作在建立能來回傳遞到用戶端的編碼文字時,也採用此同個類別。

private string EncodeText(string text) {
  StringWriter writer = new StringWriter();
  LosFormatter formatter = new LosFormatter();
  formatter.Serialize(writer, text);
  return writer.ToString();
}

前面一小段程式碼,示範如何使用 LosFormatter 以編碼和雜湊來建立類似檢視狀態的內容。

電子郵件與垃圾郵件

文章最後要告訴您,至少有兩種常見的攻擊 (典型的 XSS 攻擊和滑鼠點擊攻擊) 是利用引誘沒防戒心的使用者,按下引誘或虛假連結來進行的。儘管有反垃圾郵件的過濾程式可以用,這些連結還是常常就在我們的信箱裡,因為只要花幾塊錢就可以購買到大量的電子郵件地址,另外一種建置大量電子郵件清單的主要方法,就是掃描公共網頁,只要找到類似電子郵件的資訊,就予以擷取。

如果網頁顯示了一個電子郵件地址,則 Web Robot 很可能會取得該地址,只是時間問題而已。真的嗎?嗯,其實那還與您顯示電子郵件地址的方法有關。如果您採用硬式編碼,那是一定的,但如果您以其他方式來呈現您的地址,例如,dino-at-microsoft-dot-com,我不確定那樣是否可以躲過 Web Robot 的掃描,不過我可以肯定的說,想要與您聯絡的人一定覺得很麻煩。

總之,您需要想出一個能動態產生電子郵件地址的方法,像是利用 mailto 連結。Marco Bellinaso 就是針對此目的撰有一個免費元件,您可以從 DotNet2TheMax 網頁上取得完整的原始程式碼。

總結

您有沒有想過,Web 可能是所有 Runtime 環境的最大敵人?主要原因是,每個人都能使用 Web,每個人都想利用它來傳遞資訊 (無論好壞)。反過來說,建立一個不接受使用者輸入的 Web 應用程式,不就又沒意義了嗎?

反正事實就是,無論您的防火牆再堅固,您安裝時常安裝補充程式,只要您執行的 Web 應用程式繼承安全漏洞,駭客遲早會通過主要門檻 (連接埠 80),直攻系統重鎮的。

ASP.NET 應用程式不比其他 Web 應用程式還易受攻擊,但也沒比它們還安全。安全性與易受攻擊性皆來自編碼方法,而這與在此領域的經驗以及團隊合作皆息息相關。如果網路不安全,應用程式的安全性肯定低,反之,無論網路的安全性再高,管理得再好,只要應用程式不穩固,駭客還是有辦法攻擊的。

ASP.NET 的優點是,它提供了幾個好用的工具,您只須按幾次滑鼠,就能使安全防護更上一層樓,但請切記,這並 不是 完全有效。您千萬不能只依賴 ASP.NET 的內建解決方案,但也不應忽略它。您需要盡量充實有關常見攻擊的知識。

本文列舉一些內建功能,並解說攻擊與防禦的背景。至於偵測進行中的攻擊又是另外一回事,可能需要撰寫另一篇文章來闡述。

相關資源

Writing Secure Code,作者:Michael Howard 和 David LeBlanc

TechNet Magazine,Theft On The Web:Prevent Session Hijacking

作者簡介

Dino Esposito 目前在義大利擔任 Wintellect 講師兼顧問。是《Programming Microsoft ASP.NET》一書與新書《Introducing Microsoft ASP.NET 2.0》(兩本皆為 Microsoft Press 書籍) 的作者,他大半時間都在教授 ASP.NET 與 ADO.NET 的課程,並在討論會中演講。歡迎參閱 Dino 的網誌 (Blog),網址為:http://weblogs.asp.net/despos

From MSDN

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30193/viewspace-521171/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论