本文章是由機器翻譯。

安全性簡報

再度探討 Web 應用程式組態安全性

Bryan Sullivan

幾年前,在我來到 Microsoft 和安全性開發生命週期 (SDL) 團隊之前,我寫過一篇文章,闡述了不安全的 web.config 設置帶來的危險,並指出了 10 大危險源。 現在您仍可以找到這篇文章,只需在您喜歡的搜尋引擎中搜索“Top 10 Application Security Vulnerabilities in Web.Config Files”即可。 我以前提過的配置漏洞現在仍然存在,並且十分嚴重,雖然MSDN 雜誌的忠實讀者對這些漏洞可能並不十分陌生。 啟用自訂錯誤,在應用程式投入生產環境之前禁用跟蹤和調試以及對身份驗證 Cookie 要求使用 SSL,這些仍然很重要。

在本月的專欄中,我希望補充上一篇文章未涉及的內容,並討論某些更具隱蔽性但同樣嚴重的安全配置錯誤問題。 我還要介紹 Microsoft 資訊安全工具團隊研發的一款免費新工具,該工具稱為“Web Application Configuration Analyzer”,可以幫您解決上述問題。 請記住,即使是編碼最安全的 ASP.NET 應用程式,在配置不正確的情況下也會被擊潰。

EnableEventValidation

開發人員常犯的一個錯誤是為使用者提供一個選擇清單,然後假定使用者實際會選擇其中一個值。 這看起來似乎合理:如果您在頁面中添加一個 ListBox 控制項,然後使用美國所有州的清單進行預填充,您預期返回的是“華盛頓”、“佐治亞”或“德克薩斯”,而不會想到返回“Foo”、“!@#$%”或“

”。. 在通過流覽器以傳統方式使用應用程式時,可能無法像以上示例那樣指定值,但卻有多種方式,不用流覽器就可以訪問 Web 應用程式! 使用 Web 代理工具,如 Eric Lawrence 的 Fiddler(這一直是我最喜歡的用來查找 Web 應用程式中安全性漏洞的工具之一,可以在如下網址下載:fiddler2.com),您可以隨意向任何表單欄位發送任何值。 如果您的應用程式沒有為這種可能性做準備,可能就疏忽了一些有潛在危險的方式。

EnableEventValidation 配置設置是一種深層防禦機制,有助於防範此種性質的攻擊。 如果惡意使用者試圖向接受確定值清單的控制項(如 ListBox。TextBox 控制項不在此列,因為它的性質已經可以接受任何值)發送意外值,則應用程式將檢測到攻擊並引發異常。

不好的代碼:

<configuration>

  <system.web>

    <pages enableEventValidation="false"/>

好的代碼:

<configuration>

  <system.web>

    <pages enableEventValidation="true"/>

PasswordFormat

ASP.NET(從 ASP.NET 2.0 開始)中包含的成員身份提供程式框架是一個很棒的功能,使開發人員無需一次又一次地重新創建成員身份功能。 通常,保留內置提供程式的預設設置是最安全的。 如果更改了成員身份配置設置,安全性會大大降低。

PasswordFormat 設置就是其中一個很好的示例,此設置確定如何存儲使用者密碼。 您可以有三種選擇:直接存儲,即以純文字方式存儲密碼;加密存儲,即在存儲密碼前對其進行加密;雜湊存儲,即存儲密碼的雜湊值而不是存儲密碼本身。 這幾個選項中,直接存儲是最不理想的方式。 永遠不要以純文字格式存儲密碼。 加密存儲會好得多,雜湊存儲是最佳方式,因為存儲秘密的最佳方式就是根本不存儲。 然而,由於沒有辦法從雜湊值檢索原始密碼,所以在使用者忘記自己的密碼時,您將不能為其恢復密碼。

不好的代碼:

<configuration>

  <system.web>

    <membership>

      <providers>

        <clear/>

        <add name="AspNetSqlMembershipProvider" 

             passwordFormat="Clear"

             ...
/>

較好的代碼:

<configuration>

  <system.web>

    <membership>

      <providers>

        <clear/>

        <add name="AspNetSqlMembershipProvider" 

             passwordFormat="Encrypted"

             ...
/>

最好的代碼:

<configuration>

  <system.web>

    <membership>

      <providers>

        <clear/>

        <add name="AspNetSqlMembershipProvider" 

             passwordFormat="Hashed"

             ...
/>

MinRequiredPasswordLength 和 MinRequiredNonalphanumericCharacters

成員身份設置中有兩個值需要改變預設狀態,即 MinRequiredPasswordLength 和 MinRequiredNonalphanumericCharacters。 對於 AspNetSqlMembershipProvider 物件,這些設置預設為至少需要使用長度為 6 個字元的密碼,且不需要非字母數位字元。 為提高安全性,這些設置要求需要大大提高。 您應該要求使用至少 10 個字元長的密碼,並至少包含兩個非字母數位字元。 更好的方式是最少設置 14 個字元,並至少包含 4 個非字母數位字元。

密碼長度和複雜性確實是一把雙刃劍:您要求使用者設置的密碼越長越複雜,這些密碼抵禦窮舉攻擊的能力越強,但同時使用者記不住密碼且不得不寫下密碼的情況越可能發生。 雖然寫下密碼看似是一個可怕的潛在安全性漏洞,但很多安全專家認為這樣做利大於弊。 著名的安全大師 Bruce Schneier 就是其中之一,他建議使用者創建長而複雜的密碼,將其保存在錢包裡,因為人們用錢包保存小紙片較安全。

不好的代碼:

<configuration>

  <system.web>

    <membership>

      <providers>

        <clear/>

        <add name="AspNetSqlMembershipProvider" 

             minRequiredPasswordLength="6"

             minRequiredNonalphanumericCharacters="0"

             ...
/>

好的代碼:

<configuration>

  <system.web>

    <membership>

      <providers>

        <clear/>

        <add name="AspNetSqlMembershipProvider" 

             minRequiredPasswordLength="14"

             minRequiredNonalphanumericCharacters="4"

             ...
/>

Microsoft 連線安全網站 (microsoft.com/protect/fraud/passwords/create.aspx) 也建議使用者寫下自己的密碼,並提供了如何創建和確保強式密碼安全的附加資訊。

ValidateRequest

跨網站腳本 (XSS) 仍是最常見的 Web 漏洞。 Cenzic Inc.7 月份發佈的一份報告 表明,上半年內,XSS 漏洞在所有 Web 攻擊中占 28%。 由於 XSS 漏洞可能導致嚴重後果(我過去經常將 XSS 稱為“Web 緩衝區溢位”),開發人員應竭盡所能防止其應用程式遭受此種攻擊。 防範措施最好不花分文,ValidateRequest 能夠做到這一點。

不好的代碼:

<configuration>

  <system.web>

    <pages validateRequest="false" />

好的代碼:

<configuration>

  <system.web>

    <pages validateRequest="true" />

ValidateRequest 工作時將測試使用者輸入中是否存在常見的攻擊模式,如輸入字串是否包含尖括弧 ( <)。 如果存在這樣的模式,則應用程式將引發異常,並停止處理請求。 雖然這本身不能構成一個完整的解決方案,您還需要一直應用輸出編碼和輸入驗證/淨化邏輯(就像內置在 Microsoft Web Protection Library 中的邏輯一樣),但 ValidateRequest 確實能夠阻止很多種常見的 XSS 攻擊。 最好盡可能將 ValidateRequest 置於啟用狀態。

MaxRequestLength

允許使用者對您的應用程式做出任意大的 HTTP 請求並不明智。 因為這樣容易遭受拒絕服務 (DoS) 攻擊,此時一個攻擊者就可以用盡您的所有頻寬、處理器週期或磁碟空間,導致您的應用程式無法服務于任何其他合法使用者。

為防止此類情況發生,您可以將 MaxRequestLength 屬性適度地設置為較小的值。 預設值是 4096KB (4MB)。 對於正常和異常的請求大小,不同的應用程式有不同的要求,所以很難制定一個通用的規則規定設置怎樣的 MaxRequestLength 值。 因此,這次不再舉例說明“不好”和“好”的設置,只是建議您記住:此值設置越高,您遭受 DoS 攻擊的風險越大:

<configuration>

  <system.web>

    <httpRuntime maxRequestLength="4096"/>

EnableViewStateMac

我在 2010 年 7 月的“安全簡報”專欄發佈過關于針對視圖狀態安全進行 EnableViewStateMac 設置的文章 (msdn.microsoft.com/magazine/ff797918)。 提醒一下沒有閱讀過此文的讀者,EnableViewStateMac 可以防止攻擊者篡改用戶端視圖狀態。 啟用 EnableViewStateMac 時,ASP.NET 應用程式會將加密訊息驗證碼 (MAC) 添加到 hidden __VIEWSTATE 表單值中。 攻擊者無法確定有效的 MAC 以發起任意攻擊(比如試圖破壞攻擊目標的視圖狀態以注入某些惡意 JavaScript),因此,如果攻擊者試圖以這種方式篡改視圖狀態,MAC 將無效且 ASP.NET 應用程式將阻止該請求。

不好的代碼:

<configuration>

  <system.web>

    <pages enableViewStateMac="false"/>

好的代碼:

<configuration>

  <system.web>

    <pages enableViewStateMac="true"/>

如果您在伺服器場環境中部署應用程式,請務必為 MAC 手動指定金鑰,而不是令應用程式自動生成隨機金鑰。 (如果您沒有手動指定金鑰,則場中的每個電腦將自動生成不同的金鑰,任何電腦創建的視圖狀態 MAC 將被其他電腦視為無效並受到其他電腦阻止。)

手動創建金鑰時要遵守一些額外的規則,以確保視圖狀態最佳安全性。 首先,確保指定一種 SDL 批准的加密演算法。 對於使用 Microsoft .NET Framework 3.5 或更早版本的應用程式,這意味著使用 SHA1(預設演算法)或 AES。 對於使用 .NET Framework 4 的應用程式,您還可以使用 HMACSHA256、HMACSHA384 或 HMACSHA512。 請避免使用 MD5 等較弱的演算法。

不好的代碼:

<configuration>

  <system.web>

    <machineKey validation="MD5" validationKey="..."/>

好的代碼:

<configuration>

  <system.web>

    <machineKey validation="AES" validationKey="..."/>

選擇強金鑰和選擇強演算法一樣重要。 可使用增強式加密亂數字生成器生成 64 位元組金鑰(使用 HMACSHA384 或 HMACSHA512 作為金鑰演算法時將生成 128 位元組金鑰)。 前面提到的 2010 年 7 月的“安全簡報”專欄提供了生成正確金鑰的參考示例代碼。

不好的代碼:

<configuration>

  <system.web>

    <machineKey validation="AES" validationKey="12345"/>

好的代碼:

<configuration>

  <system.web>

    <machineKey validation="AES" validationKey="143a907bb73069a2fe7c..."/>

ViewStateEncryptionMode

您不但需要對應用程式視圖狀態應用 MAC 以便阻止潛在攻擊者篡改視圖狀態,還需要對視圖狀態進行加密,以防止攻擊者讀取視圖狀態。 除非您完全確定您的任何視圖狀態中都沒有敏感資訊,否則最好設置 ViewStateEncryptionMode 屬性以加密和保護視圖狀態。

不好的代碼:

<configuration>

  <system.web>

    <pages viewStateEncryptionMode="Never"/>

好的代碼:

<configuration>

  <system.web>

    <pages viewStateEncryptionMode="Auto"/>

像 EnableViewStateMac 一樣,您可以為應用程式選擇多種加密演算法來加密視圖狀態。 但最好始終使用 AES,因為這是當前經過 SDL 加密標準批准的
唯一可用演算法。

不好的代碼:

<configuration>

  <system.web>

    <machineKey decryption="DES" decryptionKey=""/>

好的代碼:

<configuration>

  <system.web>

    <machineKey decryption="AES" decryptionKey=""/>

最後,請記住,如果您在伺服器場中部署應用程式,則需要手動指定金鑰。 確保將金鑰值設置為 24 位元組加密隨機值。

不好的代碼:

<configuration>

  <system.web>

    <machineKey decryption="AES" decryptionKey="12345"/>

好的代碼:

<configuration>

  <system.web>

    <machineKey decryption="AES" decryptionKey="143a907bb73069a2fe7c..."/>

UseUnsafeHeaderParsing

如果開發者飽受一個難以解決的 Bug 的困擾,他們往往實施任何自己學來的更改來解決問題,而不真正清楚自己對應用程式做了什麼。 UseUnsafeHeaderParsing 設置是此種現象的經典示例。 雖然屬性名中的“unsafe”一詞足以警告多數開發人員,但在 Internet 簡單搜索一下還是會出現成千上萬建議開發者啟用此屬性的結果。 如果您啟用了 UseUnsafeHeaderParsing,您的應用程式將忽略很多 HTTP RFC 規範,並試圖解析非正常格式的請求。 雖然這樣做使您的應用程式能夠服務于不遵守 HTTP 標準的 HTTP 用戶端(這也是很多人建議用此種辦法解決問題的原因),但同時也可能使您的應用程式遭受格式不正確的標頭的攻擊。 為保持安全,請禁用此設置。

不好的代碼:

<configuration>

  <system.
net>

    <settings>

      <httpWebRequest 

       useUnsafeHeaderParsing=

       "true"/>

好的代碼:

<configuration>

  <system.
net>

    <settings>

      <httpWebRequest 

       useUnsafeHeaderParsing=

       "false"/>

Web Application Configuration Analyzer (WACA)

我們已經瞭解了一些危險的配置設置,現在看一下能説明您自動查找代碼中此類設置的工具。人工檢查代碼雖然可行,但自動分析畢竟可以更加徹底,更加一致。同時您也會從人工檢查 XML 檔的枯燥工作中解放出來,騰出更多時間來解決更有意思的問題!

Microsoft 資訊安全工具團隊發佈了一些優秀的安全工具。其中包括 AntiXSS/Web Protection Library 和 CAT.NET,我們已將這兩個工具作為 Microsoft SDL 的一部分強制加入內部 .NET Framework Microsoft 產品和服務之中。在最新的版本中,WACA 設計為檢測潛在的危險配置錯誤,如我在本文及以前的關於 10 大
常見 web.config 漏洞的文章中所述的錯誤。WACA 檢查的一些示例:

  • 是否啟用了跟蹤?
  • MaxRequestLength 是否太大?
  • 是否禁用了 HttpOnly Cookie?
  • 進行表單身份驗證登錄時是否需要 SSL?
  • 是否已將 EnableViewStateMac 屬性設置為 false?

另外,WACA 還可以檢查 IIS 本身的配置錯誤,以及 SQL 資料庫配置錯誤甚至系統級別問題。以下是一些具體示例:

  • 是否已禁用 Windows 防火牆服務?
  • 本地管理員是否名為“Administrator”?
  • IIS 日誌檔是否在系統驅動器上?
  • 應用程式虛擬目錄中是否啟用了執行?
  • SQL 伺服器中是否存在示例資料庫?
  • SQL 伺服器上是否啟用了 xp_cmdshell?

雖然開發人員和測試人員多數情況下可能使用 WACA 檢查應用程式配置設置,但系統管理員和資料庫管理員會發現使用 WACA 檢查 IIS、SQL 和系統設置十分有用(請參閱圖 1)。WACA 中總共包含 140 多種根據 SDL 要求和模式以及實踐代碼指南做出的檢查。

圖 1 Web Application Configuration Analyzer 規則

WACA 還有一個非常方便的功能,就是可以在 Team Foundation Server (TFS) 團隊專案中根據 WACA 掃描結果自動創建工作項或 Bug。針對從 SDL 過程範本或 MSF-Agile+SDL 過程範本創建的團隊專案使用此功能時尤其有用。在 WACA TFS 設置頁,將範本欄位“Origin”映射到值“Web Application Configuration Analyzer”。然後在查看您的 Bug 報告或趨勢圖表時,您將能過濾和深入查看 WACA 結果,以查看此功能在檢測潛在漏洞時的神奇效果(請參閱 圖 2 )。

圖 2 WACA Team Foundation Server 集成

您可以在 Microsoft IT InfoSec 小組的頁面 (msdn.microsoft.com/security/dd547422) 閱讀有關 WACA 的詳細資料,還可以觀看 WACA 專案的專案經理 Anil Revuru 提供的有關該工具的視頻演示 (msdn.microsoft.com/security/ee909463),並且,最好的是,還能下載該工具並親自試用 (tinyurl.com/3x7bgfd)。

始終檢查您的設置

您可能在開發應用程式時遵循了每一個安全開發指南和最佳實踐,最終卻因為 web.config 設定檔中一個小小錯誤而受到攻擊,這會令人十分沮喪。讓人更為惱火的是,您可能意識到 web.config files 設計為隨時可更改,以至於在完成應用程式編碼並投入生產數年後還會出現配置錯誤。因此,一直檢查您的配置設置是十分重要的,並且不但要進行手動檢查,還要使用自動化工具檢查,不僅在開發生命週期中檢查,還要在生產階段檢查。

規則運算式 DoS 攻擊後續資訊

另一個完全不同的話題:在 2010 年 5 月的“安全簡報”專欄 (msdn.microsoft.com/magazine/ff646973) 中,我寫了一篇文章,闡述了 2009 年 9 月的 OWASP Israel 大會上由 Checkmarx 演示的規則運算式 DoS 攻擊。在該專欄中,我還提供了基於 Visual Studio 資料庫專案資料生成計畫功能的規則運算式 DoS 模糊測試程式碼。雖然此方法在技術上看來很完善,也可以順利檢測出規則運算式漏洞,但生成測試資料的過程確實比較枯燥,而且該方法需要您持有 Visual Studio 資料庫專案許可證。現在我興奮地宣佈,SDL 團隊已經發佈了一個新的免費下載工具,使用該工具可以對規則運算式漏洞進行模糊測試,同時為您處理資料生成詳細資訊。該工具不依賴任何外部平臺,只需要 .NET Framework 3.5。如图 3 所示。

圖 3 SDL 規則運算式模糊程式

您可以從 microsoft.com/sdl 下載 SDL 規則運算式模糊程式。請試一試,並告訴我們您的想法。

Bryan Sullivan 是 Microsoft 安全開發生命週期團隊的一名安全專案經理,專門負責 Web 應用程式和 Microsoft .NET Framework 的安全問題。 他是“Ajax Security”(Addison-Wesley,2007)一書的作者。

衷心感謝以下技術專家對本文的審閱: Anil Revuru