本文章是由機器翻譯。

安全性簡報

檢視狀態安全性

Bryan Sullivan

有效管理 Web 應用程式中的使用者狀態可以是複雜的平衡動作的效能、 延展性、 可維護性和安全性。您管理儲存在用戶端上的使用者狀態時,尤其是明顯的安全性考量。我有說到用戶端的資料,就像處理到 5 年歷史的冰淇淋圓錐該 handing 狀態使用的同事:您可能在回,取得,但絕對 can’t 想取得回中相同的圖案時給予!

這個月 ’s] 欄中我們檢查用戶端狀態管理,在 ASP.NET 應用程式中的某些安全性含意,特別,我們會查看檢視狀態安全性]。(請注意:本文假設您 ’re 熟悉ASP.NET 檢視狀態的概念。如果不,簽出 「 的 瞭解 ASP.NET 檢視狀態 」 的陳俊銘嘉玲)。

如果您 don’t 認為有 ’s 值得保護應用程式 ’ 檢視狀態中儲存任何資料,認為一次。機密資訊可以找到其方式檢視狀態至您甚至察覺不。而且,即使您 ’re 警覺有關防止敏感資訊遺失,透過檢視狀態,攻擊可以仍然竄改檢視狀態,並為您和您的使用者造成更大的問題。幸好,ASP.NET 會有一些內建防衛以對抗這些攻擊。let’s 看看這些防禦功能可以使用方式正確。

威脅 [否]。1: 資訊洩露

在 Microsoft,開發小組會使用 STRIDE 模型將威脅分類。STRIDE 是代表的助憶鍵:

  • 假冒
  • 竄改
  • 否認
  • 資訊洩露
  • 拒絕服務
  • 提高權限

主要的兩個 STRIDE 類別從檢視狀態安全性的觀點來看關心的是資訊洩漏與竄改 (雖然成功竄改攻擊會導致一個可能提高 ; 我們稍後詳細討論的)。資訊洩漏是較簡單的說明,這些潛在威脅,讓我們討論的第一個。

其中一個最不巧的是永續性的 misconceptions 周圍檢視狀態是它是加密或某種方式無法讀取使用者。之後就所有檢視狀態字串,當然 doesn’t 尋找 decomposable:

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTY2ODcyMjkPFgIeCHBhc3N3b3JkBQlzd29yZGZpc2hkZA==" />

但是,這個字串是演算法的只是演算法的 Base64 編碼,不使用任何一種密碼編譯方面強式加密。 我們可以輕鬆地解碼,並將還原序列化使用有限的物件序列化 (LOS) 的格式子類別 System.Web.UI.LosFormatter 這個字串中:

LosFormatter formatter = new LosFormatter();
object viewstateObj = formatter.Deserialize("/wEPDwULLTE2MTY2ODcyMjkPFgIeCHBhc3N3b3JkBQlzd29yZGZpc2hkZA==");

在偵錯工具中的快速窺視 (請參閱 圖 1 ) 顯示已還原序列化的檢視狀態物件是實際一系列 System.Web.UI.Pair 物件結束與 System.Web.UI.IndexedString 物件的 「 密碼 」 的值與對應的字串值的 「 swordfish 」。

圖 1 密碼檢視狀態資料會顯示在偵錯工具的

如果您 don’t 想要跳到的撰寫您自己的程式碼,以還原序列化檢視狀態物件問題,有幾個可用的 
decoders 免費下載包括 Fritz 洋蔥 ’s ViewState 解碼器工具可以使用 alt.pluralsight.com/tools.aspx 在網際網路的良好的檢視狀態。

將檢視狀態加密

在 「 的安全性開發生命週期:SDL:開發 Demonstrably 其他安全軟體的處理程序 」 (Microsoft 按,2006年),Michael Howard 和徐維斌 Lipner 討論可用來減輕 STRIDE 威脅的技術。圖 2 顯示威脅類型和其相關聯的降低風險技術。

圖 2 的 技術,以減輕 STRIDE 威脅

威脅類型 降低技術
假冒 驗證
竄改 完整性
否認 不可否認性服務
資訊洩露 保密性
拒絕服務 可用性
提高權限 Authorization

 

因為我們處理我們的資料儲存在檢視狀態中的資訊洩漏威脅,我們需要套用機密性的降低風險技術,最有效的機密性緩和技術在這種情況下會加密。

ASP.NET 2.0 有內建的功能,來啟用檢視狀態的加密的版本 — 可以透過網頁指示詞或應用程式 ’s web.config 檔案中啟用的 [ViewStateEncryptionMode] 屬性:

<%@ Page ViewStateEncryptionMode="Always" %>

Or

<configuration>
   <system.web>
      <pages viewStateEncryptionMode="Always">

有三個可能的值為 ViewStateEncryptionMode:永遠 (檢視狀態永遠加密) ; 永不 (檢視狀態永遠不會加密) ;] 及 [自動 (檢視狀態只加密如果其中一個頁面 ’s 控制項明確地要求)。 [永遠] 和 [永遠不檢查值是相當自我闡明但自動需要一些詳細的說明。

如果伺服器控制項會保存機密的資訊,其網頁 ’s 檢視狀態至控制項可以要求頁面來呼叫 Page.RegisterRequiresViewStateEncryption 方法 (請注意在這種情況下整個檢視狀態加密,不只是對應至要求它的控制項之檢視狀態) 加密檢視狀態:

public class MyServerControl : WebControl
{
   protected override void OnInit(EventArgs e)
   {
      Page.RegisterRequiresViewStateEncryption();
      base.OnInit(e);
   }
   ...
}

但是,是一項警告。 RegisterRequiresViewStateEncryption,並不像 EnableViewStateEncryption,名為方法的原因是因為頁面可以選擇忽略要求。 如果頁面 ’s ViewStateEncryptionMode 設定為 [自動] (或 [始終]),控制 ’s 要求將被授與,並會加密檢視狀態。 如果 ViewStateEncryptionMode] 設定為 [永遠不],控制 ’s 要求將被忽略,並且檢視狀態是未受保護。

這絕對是值得注意的如果 ’re 控制項開發人員。 您應該考慮將可能的敏感性資訊的檢視狀態 (也就是永遠是個好主意)。 在極端的情況下,這會 isn’t 可能,您可以考慮覆寫控制項 ’s SaveViewState 和 LoadViewState 方法,來手動加密和解密檢視狀態。

伺服器陣列的考量

在單一伺服器的環境中 ’s 就足以讓 ViewStateEncryptionMode,但伺服器伺服陣列環境中有 ’s 一些額外的工作来做。 對稱加密演算法 (喜歡的 ASP.NET 用來加密檢視狀態 — 需要金鑰。 您可以明確地指定索引鍵在 web.config] 檔案或 ASP.NET 可以自動為您產生的金鑰。 一次,在單一伺服器環境中 ’s 好讓架構處理產生金鑰,但這 won’t 適用於伺服器伺服陣列。 每一部伺服器會產生自己的唯一索引鍵,和取得負載 
balanced 不同的伺服器之間的要求將會失敗,因為解密金鑰 won’t 相符。

您可以明確地設定密碼編譯演算法,並使用 machineKey 元素的應用程式 ’s web.config 檔中的機碼:

<configuration>
   <system.web>
      <machineKey decryption="AES" decryptionKey="143a...">

您可以選擇 AES (預設值) DES 或 3DES 加密的演算法。 這些項目,DES 明確禁止由 Microsoft SDL 密碼編譯標準,及 3DES 是強不建議使用。 我建議您最大的安全性停用 AES。

一旦您選取演算法,您必須建立索引鍵。 但是,請記住這個系統 ’s 安全性強度取決於該金鑰的強度。 don’t 使用寵物 ’s 名稱、 有效 other ’s 生日或任何容易 guessable 的值! 您必須使用密碼編譯方面強式的隨機數字。 這裡 ’s 建立一個格式 machineKey 項目所預期 (只有十六進位字元) 的程式碼片段使用.NET RNGCryptoServiceProvider 類別:

RNGCryptoServiceProvider csp = new RNGCryptoServiceProvider();
byte[] data = new byte[24];
csp.GetBytes(data);
string value = String.Join("", BitConverter.ToString(data).Split('-'));

一個至少您應該為您的金鑰產生 16 位元組的隨機值 ; 這是 SDL 的密碼編譯標準所允許的最小值]。 支援 AES 金鑰的長度上限是 24 個位元組 (48 個十六進位字元),在 Microsoft.NET Framework 3.5 及更早的以及在.NET Framework 4 32 個位元組 (64 個十六進位的字元)。 DES 支援最大的金鑰長度的唯一的 8 個位元組及 3DES 的架構版本無關的 24 個位元組的最大值。 一次,我建議您避免這些演算法,並改用 AES。

威脅 [否]。 2: 竄改

竄改是其他重大的威脅。 您可能會認為相同防止攻擊者 prying 至檢視狀態的加密防禦] 就會也會防止它們從其,變更,但這是錯誤。 加密 doesn’t 提供防禦竄改:即使是使用加密的資料 ’s 還是有可能讓攻擊者翻轉位元加密的資料。

如需在 的 圖 2 的另一個做法。 若要減輕竄改的威脅,我們需要使用資料完整性的技術。 最佳的選擇仍然是一種密碼編譯,和它仍然內建於 ASP.NET,但代替使用對稱演算法加密資料,我們使用雜湊演算法來建立訊息驗證碼 (MAC) 的資料。

要套用 MAC ASP.NET 功能稱為 EnableViewStateMac,並就像 ViewStateEncryptionMode,您可以將它套用到頁面指示詞或透過應用程式 ’s web.config 檔案:

<%@ Page EnableViewStateMac="true" %>

Or

<configuration>
   <system.web>
      <pages enableViewStateMac="true">

若要了解 EnableViewStateMac 真正做什麼] 下封面,let’s 第一次看高階檢視狀態寫入網頁時檢視狀態 MAC 是 的啟用:

  1. 頁面及參與的所有控制項的檢視狀態會收集到狀態的圖形物件。
  2. 狀態圖會序列化為二進位格式。
  3. 已序列化的位元組陣列編碼成 Base-64 字串。
  4. 基底 64 字串寫入 __VIEWSTATE 表單值,在網頁中。

在啟用檢視狀態 MAC 有三個額外的步驟,進行先前的步驟 2 和 3 之間:

  1. 頁面及參與的所有控制項的檢視狀態會收集到狀態的圖形物件。
  2. 狀態圖會序列化為二進位格式。
    a.一個秘密金鑰值被附加到已序列化的位元組陣列。
    b.密碼編譯雜湊計算新的序列化的位元組陣列。
    c.雜湊會附加至序列化的位元組陣列的結尾。
  3. 已序列化的位元組陣列編碼成 Base-64 字串。
  4. 基底 64 字串寫入 __VIEWSTATE 表單值,在網頁中。

每當此網頁張貼回伺服器時,網頁程式碼會藉由連入驗證連入的 __VIEWSTATE 狀態圖形資料 (從 __VIEWSTATE 值還原序列化),新增相同的秘密金鑰值,和 recomputing 雜湊值。如果新的 recomputed 的雜湊值,都符合連入的 __VIEWSTATE 結尾所提供的雜湊值,檢視狀態會被視為有效,並處理進行 (請參閱 的 圖 3)。否則,檢視狀態會被視為已遭他人修改,而擲回例外狀況。

圖 3 套用訊息驗證碼 (MAC)

此系統的安全性在於秘密金鑰值的機密性。這個值一律會儲存在伺服器上,在記憶體中,或在組態檔 (更多關於這稍後) — 它絕對不會寫入至頁面。即使不知道索引鍵,就會不讓攻擊者計算有效的檢視狀態雜湊。

理論上,具有足夠的運算能力的攻擊者可以反向工程索引鍵:他有知識的計算的雜湊值,並且對應的純文字的知識,並有 aren’t 太多的選項適用於雜湊演算法。他將只會有循環所有可能的金鑰值,重新計算為已知的純文字加上目前的機碼的雜湊,並與已知的雜湊相比較。一旦值相符,他知道他位於正確的機碼,並可以現在攻擊系統會。唯一的問題,這是十足的可能值的數字:預設金鑰大小為 512 的位元,這表示有 512 不同的可能性的乘冪即暴力式攻擊是完全 unfeasible 因此大型數字的 2。

利用 MAC 小於檢視狀態

因此保護您的應用程式很簡單,不將它設為 False,則,是 true,EnableViewStateMac 的預設值。不幸的是,沒有關於 EnableViewStateMac,效能影響某些使人產生誤解文件,而有些網站會鼓勵開發人員停用檢視狀態 MAC,來改善其應用程式的效能。甚至在 MSDN 線上文件 PagesSection.EnableViewStateMacProperty 是 guilty 的這個,說明:「 沒有設定為 true,如果效能是主要的考量 EnableViewStateMac 」。遵循這項建議!(但願,對此進行讀取時,文件將已經變更成更能反映出安全性考量)。

可能有對 __VIEWSTATE 參數的跨站台指令碼攻擊的弱點有其檢視狀態 MAC 停用任何頁面。在第一個-概念的這種攻擊是由 David Byrne Trustwave 的開發和 Byrne 和他的同事 Rohini Sulatycki 在黑色帽 DC 會議所示 2 月 2010年。若要執行此類攻擊攻擊者手工藝品 innerHtml 屬性頁 ’s 表單項目的的永續性的值為設有他想執行惡意的指令碼程式碼的檢視狀態圖。XML 形式這個檢視狀態圖表,也會看起來像 的 圖 4

圖 4 的 檢視狀態 MAC 攻擊的 XML 程式碼

<viewstate>
  <Pair>
    <Pair>
      <String>...</String>
      <Pair>
        <ArrayList>
          <Int32>0</Int32>
          <Pair>
            <ArrayList>
              <Int32>1</Int32>
              <Pair>
                <ArrayList>
                  <IndexedString>innerhtml</IndexedString>
                  <String>...malicious script goes here...</String>
                </ArrayList>
              </Pair>
            </ArrayList>
          </Pair>
        </ArrayList>
      </Pair>
    </Pair>
  </Pair>
</viewstate>

攻擊者接著 Base-64 編碼惡意的檢視狀態,並將這個字串附加為有弱點的頁面的 __VIEWSTATE 查詢字串參數的值。 就例如如果頁面 home.aspx,站台 www.contoso.com 上的已知有檢視狀態 MAC 停用,攻擊 URI 是 https://www.contoso.com/home.aspx?\_\_VIEWSTATE=/w143a...

所有仍是誘騙潛在受害者遵循此連結。 然後頁面程式碼會將傳入的 __VIEWSTATE 查詢字串參數從檢視狀態還原序列化,並將惡意指令碼寫成表單的 innerHtml。 當受害者取得頁面時,受害者 ’s] 瀏覽器以犧牲者 ’s 認證會立即執行攻擊者 ’s 指令碼。

這種攻擊是特別危險,因為完全略過所有一般跨網站指令碼 (XSS) 防禦。 網際網路檔案總管 8] 中的 「 XSS 篩選器不會封鎖它。 ASP.NET 的 「 ValidateRequest 功能會封鎖幾個常見的 XSS 攻擊媒介,但它不還原序列化,並分析傳入的檢視狀態,因此 ’s 也沒有說明,在此情況下。 (現在包含 Microsoft Web 保護程式庫的一部分) Microsoft Anti-Cross 網站指令碼 (XSS 反) 程式庫對 XSS 比 ValidateRequest 甚至更有效,但是,不反 XSS 程式庫可輸入 sanitization 功能也沒有它的輸出編碼的功能會是保護對抗這類攻擊。 只有實際的防禦,就是確保該 MAC 一致地套用至所有頁面的檢視狀態。

多個伺服器陣列的考量

類似 ViewStateEncryptionMode,有特殊的考量,以 EnableViewStateMac 當部署在伺服器伺服陣列環境中的應用程式。 透過的伺服陣列中的所有電腦,用於檢視狀態雜湊的密碼值必須是常數,或檢視狀態驗證將會失敗。

您可以指定驗證金鑰和 HMAC 演算法,在相同的位置,讓您指定檢視狀態加密金鑰,以及演算法中使用 — machineKey 元素的 web.config 檔案:

<configuration>
   <system.web>
      <machineKey validation="AES" validationKey="143a...">

如果您的應用程式建置在.NET Framework 3.5 或更早版本,您可以選擇 SHA1 (預設值) AES MD5 或 3DES MAC 演算法。 如果您執行.NET Framework 4,也可以選擇 MAC SHA 2 系列:HMACSHA256、 HMACSHA384 或 HMACSHA512。 這些的選擇的 MD5 明確禁止的 SDL 加密標準,及 3DES 是強不建議使用。 SHA1 也正常動作,但.NET Framework 3.5 和較舊的應用程式,它 ’s 您最佳的選擇。 .NET 架構 4 應用程式明確地設定應該與 HMACSHA512 或 HMACSHA256 驗證演算法設定。

選擇 [MAC) 演算法之後,也需要以手動方式指定驗證金鑰。 若要使用密碼編譯方面強式的隨機數字,請記住:必要時,您可以參考先前指定的金鑰產生程式碼。 您應該使用至少 128 位元組驗證 HMACSHA384 或 HMACSHA512,機碼和任何其他的演算法的最少的 64 位元機碼。

您 Can’t 隱藏弱點的檢視狀態

與易受攻擊的檔案權限或可能會隱藏在深的伺服器端程式碼中的資料庫命令不同易受攻擊的檢視狀態是很容易發現只要尋找它。 如果攻擊者想要測試頁,以查看是否已保護其檢視狀態,他只要可以讓他該網頁的要求,並提取 Base-64 編碼的檢視狀態值,從 __VIEWSTATE 表單值。 如果 LosFormatter 類別可成功地還原序列化該值,然後它已不加密。 ’s 一點技巧 — 但不是多,以判斷檢視狀態 MAC 是否已套用。

MAC 總是會套用至檢視] 狀態值的結尾,因為常數的任何給定的雜湊演算法雜湊大小,’s 很容易判斷 MAC 是否存在。 如果在使用 HMACSHA512、 MAC 是 64 個位元組 ; 如果使用 HMACSHA384 就會 48 的位元組以及任何其他已使用的演算法會 32 個位元組。 如果刪除 32、 48 個 64 位元組的最後關閉基底 64 的解碼檢視狀態的值和上述任何到相同物件為前,LosFormatter 與還原序列化,然後檢視的狀態 MAC 套用。 如果沒有這些修剪檢視狀態位元組陣列會成功還原序列化,然後檢視的狀態 MAC hasn’t 套用] 和 [頁面是容易遭受攻擊。

casaba 安全性會讓呼叫可以協助自動進行這項測試的監看員的開發人員可用的工具。 監看員是外掛程式的 Eric Lawrence ’s Fiddler Web 偵錯 Proxy 工具,和它的運作方式是被動地分析流過 Proxy 的 HTTP 流量。 它將旗標通過任何可能有弱點資源 —,就例如.aspx 頁面與遺漏一個 MAC.的 __VIEWSTATE 如果您還沒測試的程序的一部份,使用 Fiddler 和監看員,我強烈建議提供它們一試。

結論

檢視狀態的安全性就無法輕,需要特別考慮竄改攻擊最近已被示範新的檢視狀態。 我建議您利用內建於 ASP.NET 在 ViewStateEncryptionMode 和 EnableViewStateMac 安全性機制。

Bryan Sullivan   他專門用在 Web 應用程式安全性問題是為 Microsoft 安全性開發生命週期的小組的安全性程式管理員。 他 ’s 「 艾傑克斯安全性 」 (Addison-Wesley,2007年) 的作者。

多虧了要檢閱這份文件的下列的技術專家:   Michael Howard