直播中
與其他 Web 應用程序相比,XML Web 服務器應用程序的一個主要優(yōu)點就是很好地定義了傳遞到您的應用程序的整個 XML 架構(gòu)。對于應用程序設計人員和開發(fā)人員來說,這意味著您已經(jīng)知道 XML Web 服務所必須處理的數(shù)據(jù)具有有效的格式。如果接收的數(shù)據(jù)格式不正確,那么 Microsoft® SOAP Toolkit 2.0 或 .NET 框架之類的工具將過濾出該請求,這樣您就不必為此擔心了。
例如,您不必分析日期輸入的語法是否有效。日期必須具有有效的 XSD 格式,否則該請求會被丟棄。您可能需要利用結(jié)構(gòu)驗證,因此不要隱藏字符串變量中的結(jié)構(gòu)。利用 XML 的能力和靈活性可以全面描述發(fā)送和接收的數(shù)據(jù)。
不可見的服務器
黑客攻擊您的系統(tǒng)時,首先尋找的是信息。此 Web 站點是駐留在 Windows 中還是駐留在其他系統(tǒng)中?是否正在運行 Active Server Pages?是否安裝了 Index Server?是否安裝了已知的易受攻擊的組件?是否安裝了已知的易受攻擊的 CGI 應用程序?主機是否正在運行 Microsoft® SQL Server?我是否可以對此服務器進行分布式 COM (DCOM) 調(diào)用?
對于不希望受到攻擊的站點,即使非常聰明的 Internet 用戶也應該無法回答上述任何問題。黑客對您的系統(tǒng)了解得越少,對平臺的了解也越少,就越難在您的服務器上找到問題。
例如,試想一下,如果黑客只知道 XML Web 服務的 URL 為“http://www.coldrooster.com/ssf/account.asp”,他們能了解什么呢。由于此 URL 的擴展名為 .ASP,他們可以假設這是一臺運行了 Active Server Pages 的 Windows 計算機。根據(jù)黑客對 Internet Information Server 的默認配置的了解,他們已具有足夠的信息對大量的未正確配置的弱點進行攻擊。他們可對配置方法進行大量的、很可能有效的假設,并用這些假設來刺探計算機。
如果 URL 為“http://www.coldrooster.com/ssf/account/”,情況又會怎樣呢?在這種情況下,黑客得不到任何服務器所用操作系統(tǒng)的信息,也無從假設系統(tǒng)的配置。將虛擬目錄級的請求映射到某個特定的 ASP 頁是一個非常小的配置選項,但能為服務器提供很多保護。
熟悉基本 HTTP 協(xié)議的用戶可能注意到 HTTP 標頭特別指明了正在使用的 Web 服務器類型。是的,這是另一種確定計算機上操作系統(tǒng)的更為復雜的方法,但是也可以編寫 ISAPI 過濾器來刪除或替換此標頭。有關(guān)如何進行這種操作的信息,請參閱 Developing ISAPI Filters(英文),以及 IIS 程序員指南中的 SF_NOTIFY_SEND_RESPONSE(英文)通知。服務器上運行的基礎系統(tǒng)越難辨認,黑客編寫的用于在 Internet 上查找某種類型計算機的腳本失敗的可能性就越大。
但是操作系統(tǒng)本身并不是唯一的弱點。您創(chuàng)建的 ASP 頁在后端執(zhí)行 SQL 查詢并拋出異常時,會執(zhí)行什么操作?您是否將異常信息返回給用戶瀏覽器?這樣不僅指出了 Web 服務器平臺,還指出了數(shù)據(jù)庫平臺。除此之外,它還可以使用戶了解您正在進行的特定 SQL 查詢,并為他們提供信息,使其了解如何更改要輸入到窗體中的內(nèi)容以得到他們不應有權(quán)訪問的信息。
出現(xiàn)其他 COM 異常情況怎么辦?如果將異常信息傳播給用戶,黑客將會知道您的計算機上安裝了哪些 COM 組件。如果此 COM 對象是第三方 DLL,則黑客可以得到它的一個副本,并竭盡全力搜索可能存在的所有弱點。這至少使黑客有機會了解服務器上可能存在的問題。
同樣,黑客可能會利用觸發(fā) COM 異常這一事實來阻塞服務器。黑客意識到多數(shù)異常代碼路徑未經(jīng)充分測試,且常常是資源泄露或變得更糟的起因。要避免出現(xiàn)這種情況,服務器上的代碼應能捕獲所有異常情況,并且應該只返回普遍性的錯誤。對于 XML Web 服務,您應返回幾乎不帶有平臺信息的 SOAP 錯誤。您可能希望以某種方式將數(shù)據(jù)連同 ID 一起返回給用戶以便將錯誤與審核日志中的記錄進行比較,但是,請將錯誤詳細信息放在審核日志中而不是放在返回的 SOAP 錯誤中。建議應用程序設計人員創(chuàng)建自己的應用程序的 SOAP 錯誤架構(gòu),同時提供一個非常短的選項列表,并且僅返回此列表上的錯誤。調(diào)用 XML Web 服務的客戶端不必知道有關(guān) SQL 查詢異常的詳細信息,他們只需要知道出現(xiàn)了 SOAP 服務器錯誤。
如果正在使用 Microsoft® SOAP Toolkit 2.0,可以在 COM 對象上實現(xiàn) ISoapError 接口以返回您希望返回的確切的 SOAP 錯誤,而不是一般的工具包錯誤。一般的工具包錯誤可以提供大量的、有關(guān)錯誤出現(xiàn)時在服務器上所發(fā)生情況的信息。在開發(fā)階段,工具包錯誤對于調(diào)試來說是很有用的,但是它們在產(chǎn)品服務器上不應出現(xiàn)。他們可以為黑客提供大量的、具有潛在破壞性的信息。
XML Web 服務的用戶需要知道您的服務所發(fā)送和接收的 SOAP 消息的格式,以及您的服務的終點位置。這就足夠了。任何其他信息都只會為潛在的黑客提供攻擊手段以毀壞您的系統(tǒng)。要進行自我保護,應限制返回與平臺有關(guān)的信息,并消除計算機上的多余內(nèi)容,包括刪除任何有助于他人識別您的系統(tǒng)的默認虛擬目錄或腳本映射。
開發(fā)問題
對黑客來說,服務器的脆弱性與服務器上運行的代碼質(zhì)量是成反比的。它包括基礎系統(tǒng)(操作系統(tǒng)、Web 服務器和正在使用的 SOAP 工具)的質(zhì)量,以及為特定應用程序編寫的代碼的質(zhì)量。還可能包括服務器上運行的所有其他代碼,即使該代碼不是應用程序的一部分。但是從開發(fā)人員的角度而言,我們希望考慮我們能控制的問題,以及能執(zhí)行哪些特殊的操作以保證代碼的高質(zhì)量,避免增加 XML Web 服務和服務器上正在運行的其他所有應用程序的脆弱性。
緩沖區(qū)溢出
服務器上最可怕的攻擊類型是遠程用戶可以執(zhí)行惡意代碼導致系統(tǒng)完全破壞的攻擊。大多數(shù)此類攻擊都是由于緩沖區(qū)溢出錯誤造成的。這種錯誤的典型示例是:在 C 代碼中為某本地變量分配了固定長度,然后該代碼將 HTTP 請求中的信息復制到該變量中。如果您認為請求中的數(shù)據(jù)不會比您設定的值大,而對您的服務器的惡意請求可以超過該值,并導致其發(fā)送的數(shù)據(jù)在寫入到已分配的緩沖區(qū)時超出末端。對于本地變量,緩沖區(qū)存儲在堆棧中,而堆棧中還存儲了當前函數(shù)結(jié)束時要返回的代碼地址。通過寫入時超出本地變量緩沖區(qū)的末端,黑客可以覆蓋返回地址并使函數(shù)返回到他想要的任何地址,包括 Windows CreateProcess 函數(shù)的地址。要傳遞到 CreateProcess 函數(shù)的參數(shù)也會存儲在堆棧上,如果黑客覆蓋了存儲這些參數(shù)的位置,則可以有效啟動服務器上他們想要啟動的任何應用程序。
要避免這類攻擊,請不要對從請求中讀取的數(shù)據(jù)做任何假設,然后確保緩沖區(qū)的處理代碼中沒有錯誤。對于 C/C++ 程序員,應對以下函數(shù)格外小心:strcpy、strcat、memcpy、gets、sprintf、scanf 以及所有這些函數(shù)的變體(如 lstrcpy、wcscpy、CopyMemory 等等)。請注意 strncpy 函數(shù)及其他“n”函數(shù)只是略好一些,因為在這些方案中長度變量常常是由程序決定的,而且仍有可能覆蓋固定長度的緩沖區(qū)?!皀”函數(shù)中的長度參數(shù)應根據(jù)輸出緩沖區(qū)的大小而定,而非傳入字符串的大小。如果要使用這些函數(shù),請使用“n”版本并從堆中動態(tài)分配您的緩沖區(qū)以避免可能的堆棧溢出。另外,Microsoft® Visual Studio® .NET C 編譯器支持新的 /GS 開關(guān),該開關(guān)可使代碼不會出現(xiàn)許多常見的緩沖區(qū)溢出問題。
利用 .NET 框架和管理代碼,可以消除大多數(shù)潛在的緩沖區(qū)溢出問題。Microsoft 設計 .NET 框架時,意識到了垃圾回收的好處,以及如何消除由傳統(tǒng)的緩沖區(qū)處理方式引起的問題,所以他們提供了管理代碼的能力。必須注意管理代碼和非管理代碼間的交互問題。但是至少可以在您需要時適當保證應用程序的安全。
檢查錯誤
檢查所有調(diào)用函數(shù)的返回代碼。如果正在調(diào)用 Win32 API,請確保調(diào)用已成功完成。如果正在分配內(nèi)存,請確保未返回 NULL 值。如果正在進行 COM 調(diào)用,特別是正在使用 Microsoft® Visual Basic® 進行調(diào)用并且已指定“On Error Resume Next”語句,請確保未出現(xiàn)異常。同樣,不要對這類調(diào)用的結(jié)果做任何假設。
如果正在調(diào)用 Win32 安全函數(shù),應特別小心。例如,如果正在調(diào)用 ImpersonateLoggedOnUser,應檢查返回代碼是否存在錯誤,否則將難以為用戶提供較高的安全環(huán)境。當您的 Web 應用程序配置為在 IIS 上以“進程內(nèi)”方式運行時要格外注意這一點,因為代碼可能以本地系統(tǒng)帳戶運行,這在本地計算機上幾乎沒有限制。還應注意某些交叉的 COM 調(diào)用同樣可能在具有較高權(quán)限的線程中運行。
盡早、盡快地驗證輸入
XML Web 服務接收請求時,您應做的第一件事就是驗證提交的數(shù)據(jù)。根據(jù)架構(gòu)進行 Web 服務說明語言 (WSDL) 驗證將會捕獲許多錯誤,但是您應立即執(zhí)行所需的任何應用程序級的驗證。包括檢查特殊字符、檢查特定范圍內(nèi)的數(shù)值、檢查字符串長度,等等。即使認為所有請求必須來自特定的應用程序,也應在進行證明之前假定傳入數(shù)據(jù)是無效的。事實是對 XML Web 服務的請求可以來自任何地方。如果對數(shù)據(jù)進行假設,應假定數(shù)據(jù)可能來自某個惡意用戶。
參數(shù)驗證代碼能夠快速地完成也是很重要的。識別無效請求的速度越快越好。否則 XML Web 服務容易遭受拒絕服務攻擊。如果您的服務器處理非法請求的時間較長,則很可能不能為合法請求提供服務。始終應用與專用數(shù)據(jù)同等的安全級別來對待消耗時間和資源的操作。如果必須執(zhí)行耗時的 SQL 查詢,或者某個操作要求具有很強的處理能力,則首先要確保請求的合法性。用戶是否是合法用戶?對請求進行身份驗證不僅能防止無效用戶使用您服務器上的資源,并且提供了跟蹤審核日志中的錯誤使用情況的能力,使您可以發(fā)現(xiàn)特定用戶非法使用資源的情況。如果正在驗證輸入,應首先驗證用戶的憑據(jù)。如果使用普通 HTTP 身份驗證機制,則在代碼調(diào)用之前就會為您進行用戶身份驗證。
關(guān)閉后門
有時在項目的開發(fā)階段提供一種方法,以便在服務器上解決某些問題是非常合適的。例如,XML Web 服務經(jīng)常會生成一個密鑰以便在多次調(diào)用之間標識同一個用戶,或在這些調(diào)用之間維護某種狀態(tài)。為方便調(diào)試經(jīng)常會添加一段額外的代碼以接受由所有密鑰組成的密鑰,而不是生成真正的密鑰。但是,如果確實出于合法調(diào)試的目的提供了能避免某些檢測的機制,請確保在 XML Web 服務生效之前刪除這些后門。
同樣,請避免提供能忽略安全性問題的精巧機制,即使您認為從長遠來講它有助于支持服務的長期運行。請考慮 XML Web 服務正在進行應用程序級身份驗證的情況。以下做法可能是很吸引人的:即將秘密的管理員級用戶名硬編碼到您的代碼中,這樣就可以使那些忘記了自己的管理員帳戶密碼的人能夠進入系統(tǒng)。但是,第一個用戶使用了此后門后,機密就泄露了,此代碼的所有其他用戶將很容易受到攻擊。
事實上,甚至在第一次合法使用后門之前此機密就有可能泄露。如果后門帳戶和密碼在代碼中存儲為字符串,則其他人很容易通過交付的二進制文件看到已在代碼中定義的任何字符串。如果黑客在某個 DLL 中看到類似“SecretAdministrativeUser”的字符串,他就會懷疑此字符串可能是進入代碼的后門并嘗試使用它。
最后,關(guān)于后門,您不應提供通用方法來收集服務器上的信息。雖然它通常有助于為產(chǎn)品提供支持,但在很多情況下,它會產(chǎn)生相反的結(jié)果。不要創(chuàng)建可以查看或下載配置文件或系統(tǒng)中源代碼的代碼。盡管創(chuàng)建這類代碼便于分析服務器上的異常情況,但是黑客也會利用它得到同樣的信息。通常,用戶名和密碼存儲在配置文件中,而且很多公司認為其源代碼的知識產(chǎn)權(quán)是其最寶貴的資產(chǎn)。當您考慮到這種能力通常也能查看服務器上其他應用程序的文件時,上述風險會更大。所以,即使 XML Web 服務代碼在這些能力面前是無懈可擊的,服務器上仍可能存在較易受到攻擊的應用程序。
總結(jié)
對 Web 系統(tǒng)的攻擊確實發(fā)生過,例如紅色代碼蠕蟲病毒及其變體就是非常令人頭疼的例子。幸好,可以采取一些措施來減少 XML Web 服務的風險級別。希望我們能使您了解某些可能出現(xiàn)的弱點以及如何避免這些弱點,這樣,您就可以創(chuàng)建安全的 XML Web 服務了。