ViewStateUserKey簡單介紹

ViewStateUserKey


轉載自:https://msdn.microsoft.com/zh-cn/library/ms972969.aspx#XSLTsection133121120120

從 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。)

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

圖 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 找到一篇非常好的文章。

發佈了42 篇原創文章 · 獲贊 19 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章