大多數 ASP.NET Web 應用程序都涉及數據訪問。許多應用程序都會收集數據並將其存儲在數據庫或文件中,要存儲的數據通常基於來自用戶的信息。由於原始數據可能來自不受信任的來源,信息是以持久格式存儲的,並且您希望確保未經授權的用戶不能直接訪問您的數據源,因而您需要特別注意與數據訪問有關的安全問題。本主題中所介紹的最佳操作將幫助您提高 ASP.NET Web 應用程序中的數據訪問的安全性。
儘管遵循編碼和配置最佳做法可以提高應用程序的安全性。但還有一點也很重要,那就是應經常執行 Microsoft Windows 和 Internet 信息服務 (IIS) 的最新安全更新以及 Microsoft SQL Server 或其他數據源軟件的所有安全更新,以使您的 Web 服務器始終保持在最新狀態。
有關編寫安全代碼和保護應用程序的最佳做法的更詳細信息,請參見 Michael Howard 和 David LeBlanc 合著的“Writing Secure Code”(《編寫安全代碼》)一書,也可以參見“Microsoft Patterns and Practices”(Microsoft 模式與實踐)網站中提供的指南。
保護數據源訪問的安全
以下各節提供了有關幫助保護數據訪問的不同方面的信息。
連接字符串
連接到數據庫需要連接字符串。由於連接字符串可能包含敏感數據,因此您應當遵循以下準則:
不要以純文本形式存儲連接字符串。爲了確保與數據庫服務器之間的連接的安全性,建議您使用受保護的配置來對配置文件中的連接字符串信息進行加密。有關更多信息,請參見
使用集成安全性連接到 SQL Server
如果可能,請使用集成安全性,而不要使用顯式的用戶名和密碼連接到 SQL Server 實例。這有助於避免危及連接字符串的安全以及泄漏用戶 ID 和密碼。
建議您確保運行 ASP.NET 的進程(例如應用程序池)的標識是默認進程帳戶或受限用戶帳戶。有關更多信息,請參見 。
SQL Server 數據庫權限
限制 SQL 操作
SQL Server Express Edition
在開發 Web 應用程序時用作測試數據庫。在準備好部署應用程序時,可以將數據庫從 SQL Server Express Edition 轉移到 SQL Server 的成品實例中。
如果您正在運行可以使用模擬功能的網站並且可以控制所模擬的用戶的特權,那麼可以使用該版本。實際上,此策略僅當應用程序運行於局域網(而非公共網站)上時纔可行。
有關如何在 IIS 中將文件擴展名映射到 ASP.NET 的信息,請參見。
Microsoft Access 數據庫
XML 文件
SqlDataSource 控件或其他數據源控件的屬性的方式來設置連接字符串,而應當將連接字符串存儲在站點的 Web.config 文件中。有關示例,請參見如何:確保使用數據源控件時連接字符串的安全。使用受保護的配置加密配置信息。防止惡意用戶輸入
如果應用程序要接受用戶輸入,則需要確保輸入中不包含可能危及應用程序的惡意內容。惡意用戶輸入可用於發動下面的攻擊:
-
腳本注入 腳本注入攻擊試圖嚮應用程序發送可執行的腳本,意欲使其他用戶運行該腳本。典型的腳本插入攻擊是向數據庫中存儲腳本的頁發送腳本,以使查看數據的其他用戶在不經意間運行該代碼。
-
SQL 注入 SQL 注入攻擊試圖創建 SQL 命令以取代或擴充應用程序內置的命令,從而危及數據庫(可能還有運行數據庫的計算機)的安全。
通用準則
對於所有用戶輸入,請遵循以下準則:
-
儘可能使用驗證控件,以限定用戶輸入可接受的值。
-
在運行服務器代碼之前,請始終確保 IsValid 屬性的值爲 true。如果值爲 false,則意味着一個或多個驗證控件未通過驗證檢查。
-
應始終執行服務器端驗證(即使瀏覽器也執行客戶端驗證)以防止用戶跳過客戶端驗證環節。對於 CustomValidator 控件尤其應如此;不要使用“僅客戶端驗證”邏輯。
-
始終在應用程序的業務層再次驗證用戶輸入。不要依賴於調用進程來提供安全的數據。例如,如果正在使用 ObjectDataSource 控件,則可向執行數據更新的對象添加冗餘驗證和編碼。
腳本注入
若要避免腳本注入攻擊,請遵循以下準則:
-
採用 HtmlEncode 方法對用戶輸入進行編碼,該方法可將 HTML 轉換爲文本表示形式(例如,將 <b> 轉換爲 <b>),這有助於防止在瀏覽器中執行標記。
-
在使用參數對象將用戶輸入傳遞給查詢時,可以爲數據源控件的預查詢事件添加處理程序並在這些事件中進行編碼。例如,如果處理 SqlDataSource 控件的 Inserting 事件,可以在該事件中,在執行查詢之前對參數值進行編碼。
-
如果正在使用帶綁定字段的 GridView 控件,則可將 BoundField 對象的 HtmlEncode 屬性設置爲 true。這會使 GridView 控件在行處於編輯模式下時對用戶輸入進行編碼。
-
對於可以進入編輯模式的控件,建議您使用模板。例如,GridView、DetailsView、FormView、DataList 和 Login 控件可以顯示可編輯的文本框。但是,除 GridView 控件之外(請參見上一條),這些控件不會自動驗證用戶輸入或對用戶輸入進行 HTML 編碼。因此,建議您爲這些控件創建模板,在模板中包括輸入控件(例如 TextBox 控件)並添加驗證控件。此外,在提取控件的值時,應對其進行編碼。
SQL 注入
若要避免 SQL 注入攻擊,請遵循以下準則:
-
不要通過將字符串(尤其是那些包括了用戶輸入的字符串)串聯在一起來創建 SQL 命令,而應當使用參數化查詢或存儲過程。
-
如果要創建參數化查詢,則可使用參數對象來建立參數的值。有關詳細信息,請參見對 SqlDataSource 控件使用參數和對數據源控件使用參數。
加密視圖狀態數據
數據綁定控件(例如 GridView 控件)有時需要保存被視爲敏感內容的信息。例如,GridView 控件可能要在 DataKeys 屬性中維護一個鍵的列表,即使該信息並不顯示。在往返行程之間,控件會將該信息存儲在視圖狀態中。
視圖狀態信息進行了編碼,並與頁的內容一起存儲,未經授權的源無法解碼和查看視圖狀態信息。如果必須在視圖狀態中存儲敏感信息,可以要求頁對視圖狀態數據進行加密。若要加密數據,請將頁的 ViewStateEncryptionMode 屬性設置爲 true。有關更多信息,請參見保證視圖狀態的安全。