設定資料存取的安全性
更新:2007 年 11 月
大部分的 ASP.NET Web 應用程式都涉及到資料存取問題。許多應用程式會收集要存放至資料庫或檔案的資料,而要存放的資料通常是根據來自使用者的資訊。因為原始資料可能來自不受信任的來源,資訊是以永續性的格式儲存,也因為要確定未授權的使用者無法直接存取您的資料來源,所以必須特別注意伴隨資料存取所產生的安全性問題。此主題中的資訊描述在 ASP.NET Web 應用程式中,有助於改善資料存取安全性的最佳做法。
雖然下列編碼和組態最佳作法有助於改進應用程式的安全性,但使用 Microsoft Windows 和網際網路資訊服務 (IIS) 的最新安全性更新,以及 Microsoft SQL Server 或其他資料來源軟體的任何安全性更新,持續讓 Web 伺服器保持最新狀態仍然很重要。
如需撰寫安全程式碼和保護應用程式安全性之最佳作法的詳細資訊,請參閱 Michael Howard 和 David LeBlanc 所著的《撰寫安全的程式碼》(英文),或者查閱 Microsoft 典範與實例所提供的指南。
設定資料來源存取的安全性
下列章節提供的資訊,有助於保護資料存取的各個方面。
連接字串
連接到資料庫時需要有連接字串。因為連接字串可能包含機密資料,建議遵循以下方針︰
請不要在頁面中儲存連接字串。例如,避免將連接字串設定為 SqlDataSource 控制項或其資料來源控制項的宣告性屬性,而是將連接字串儲存在網站的 Web.config 檔案中。如需範例,請參閱 HOW TO:使用資料來源控制項時保護連接字串。
請不要以純文字格式儲存連接字串。如果想要加強與資料庫伺服器連線的安全性,建議您使用受保護的組態,來加密組態檔中的連接字串資訊。如需詳細資訊,請參閱使用受保護的組態加密組態資訊。
使用整合式安全性連接 SQL Server
如果可行的話,請使用整合式安全性連接到 SQL Server 的執行個體,而不要使用明確的使用者名稱和密碼。這樣有助於避免發生連接字串被盜用,而公開您的使用者 ID 和密碼的可能性。
建議確認執行 ASP.NET 的處理序識別 (例如,應用程式集區),是預設的處理序帳戶或受限制的使用者帳戶。如需詳細資訊,請參閱 ASP.NET 模擬。
在不同網站連接到不同 SQL Server 資料庫的情況下,可能無法使用整合式安全性。例如,在 Web 主機 (Web-hosting) 網站上,一般會指派不同的 SQL Server 資料庫給每位客戶,但所有使用者都會以匿名使用者的身分使用 Web 伺服器。在這類情況中,您需要使用明確的認證連接到 SQL Server 的執行個體。請確定您以安全的方式存放認證,本主題的連接字串中將詳加說明。
SQL Server 資料庫使用權限
對於在應用程式中用來連接到 SQL Server 資料庫的使用者 ID,建議您最好只指派最基本的權限給該 ID。
限制 SQL 作業
資料繫結控制項可以支援廣泛的資料作業,包括選取、插入、刪除和更新資料的資料表 (Data Table) 中的記錄。建議您將資料控制項設定為只能執行頁面或應用程式所需的最基本功能。例如,如果控制項不得允許使用者執行刪除資料,資料來源控制項就不要包括刪除查詢,並且不要啟用控制項中的刪除功能。
SQL Server Express Edition
當處理序附加至 SQL Server Express Edition 資料庫 (.mdf 檔案) 時,處理序必須具備系統管理員權限。一般而言,這會使 SQL Server Express Edition 資料庫無法在實際執行的網站上使用,因為 ASP.NET 處理序不會 (且不應該) 以系統管理員權限執行。因此,SQL Server Express Edition 資料庫只能在下列狀況下使用︰
在開發 Web 應用程式時用來做為測試資料庫。當準備好要部署應用程式時,您可以將資料庫從 SQL Server Express Edition 轉換為 SQL Server 的實際執行個體。
如果您在執行可以模擬的網站請使用它,就可以控制模擬使用者的權限。實際上,這種策略只能於應用程式是在區域網路 (不是公開網站) 上執行時使用。
將 .mdf 檔案存放在網站的 App_Data 資料夾中,因為此資料夾的內容不會傳回至直接的 HTTP 要求。您也應該使用網站之 Web.config 檔中的下列項目,將 .mdf 副檔名對應至 IIS 中的 ASP.NET,以及對應至 ASP.NET 中的 HttpForbiddenHandler 處理常式:
<httpHandlers> <add verb="*" path="*.mdf" type="System.Web.HttpForbiddenHandler" /> </httpHandlers>
如需如何將副檔名對應到 IIS 中之 ASP.NET 的詳細資訊,請參閱 HOW TO:登錄 HTTP 處理常式.
Microsoft Access 資料庫
Microsoft Access 資料庫 (.mdb 檔案) 包含的安全性功能少於 SQL Server 資料庫。在實際執行的網站上不建議使用 Access 資料庫。但是,如果有原因必須使用 .mdb 檔案做為部分 Web 應用程式,請遵循以下方針︰
將 .mdb 檔案儲存放在網站的 App_Data 資料夾中,因為此資料夾的內容不會傳回至直接的 HTTP 要求。您也應該使用網站之 Web.config 檔中的下列項目,將 .mdb 副檔名對應至 IIS 中的 ASP.NET,以及對應至 ASP.NET 中的 HttpForbiddenHandler 處理常式:
<httpHandlers> <add verb="*" path="*.mdb" type="System.Web.HttpForbiddenHandler" /> </httpHandlers>
如需如何將副檔名對應到 IIS 中之 ASP.NET 的詳細資訊,請參閱 HOW TO:登錄 HTTP 處理常式.
為讀取和寫入 .mdb 檔案的使用者帳號,加上適當的使用權限。如果網站支援匿名存取,通常這會是本機 ASPNET 使用者帳戶或 NETWORK SERVICE 帳戶。因為 Access 必須建立 .ldb 檔案來支援鎖定,使用者帳戶必須在包含 .mdb 檔案的資料夾中擁有寫入使用權限。
如果資料庫使用密碼保護,請不要使用 AccessDataSource 控制項來建立對它的連線,因為 AccessDataSource 控制項不支援傳遞認證。請使用具有 ODBC 提供者的 SqlDataSource 控制項,並在連接字串中傳遞認證。請確定已如此主題中連接字串內容所述般地保護連接字串的安全。
XML 檔案
如果資料存放在 XML 檔案中,請將 XML 檔案放在網站的 App_Data 資料夾中,因為此資料夾的內容不會傳回以回應直接 HTTP 要求。
防範惡意使用者輸入
如果應用程式接受來自使用者的輸入,您需要確認輸入內容不包含會危害應用程式的惡意內容。惡意的使用者輸入可以用來執行下列攻擊︰
指令碼插入:指令碼插入攻擊會嘗試將可執行的指令碼傳送到應用程式,以便其他使用者執行此指令碼。典型的指令碼插入攻擊會傳送指令碼到指令碼所儲存的資料庫頁面,所以其他檢視資料的使用者會不慎執行此程式碼。
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。
快取
啟用用戶端模擬,並根據用戶端識別從資料來源擷取結果時,建議您避免將敏感性資訊儲存在 Cache 物件中。如果啟用快取,所有使用者都能夠檢視單一使用者的快取資料,而且敏感資訊可能會公開至不必要的來源。當識別組態項目的 impersonate 屬性設定為 true,並且 Web 伺服器上的應用程式已停用匿名識別時,就會啟用用戶端模擬。