目的:
對輸入的字串長度,范圍,格式和類型進行約束.
在開發ASP.NET程序時使用請求驗證防止注入攻擊.
使用ASP.NET驗證控件進行輸入驗證.
對不安全的輸出編碼.
使用命令參數集模式防止注入攻擊.
防止錯誤的詳細信息被返回到客戶端.
概述 :
你應該在程序中驗證所有的不信任輸入.你應該假定所有的用戶輸入都是非法的.用戶可以在應用程序中提供表單字段,查詢字串,客戶端cookies和瀏覽器環境值比如用戶代理字串和IP地址等.
弱輸入校驗通常為注入攻擊提供了機會.下面是常見的利用弱輸入校驗或無輸入校驗進行攻擊的手段.
SQL 注入(SQL injection). 如果你使用用戶的輸入值來動態構造SQL語句,那么數據庫可能執行攻擊性的有害SQL語句.
跨站腳本(Cross-site scripting). 跨站腳本攻擊利用網頁驗證漏洞注入客戶端腳本.接下來這些代碼被發送到受信任的客戶端電腦上并被瀏覽器解釋執行.因為這些代碼來自受信任的站點,所以瀏覽器無法得知這些代碼是有害的.
未授權的文件訪問(Unauthorized file access).如果你的代碼從調用者那里接受輸入,惡意用戶可以看到你對文件的操作過程從而訪問那些受保護的文件或者使用你的代碼注入非法數據.
注意 : 注入攻擊可通過使用HTTP或HTTPS Secure Socket Layer(SSL) 連接. 傳輸加密技術不能用來防御攻擊.
通常的輸入驗證方法總結如下.你應在所有的需要通過網絡輸入的地方進行驗證,比如文本框和其它表單輸入字段, 查詢字串參數,cookies,服務器端變量和網絡方法參數.注意,過濾策略應該是只允許正確的輸入然后拒絕非法輸入.這是因為定義正確的輸入策略比過濾所有的非法輸入要容易,那通常很難包括所有的非法輸入.
通入如下幾個方面驗證輸入內容:
約束.驗證是否輸入的是正確的類型,字符長度,格式和范圍.可以應用ASP.NET驗證控件來約束服務器控件輸入.約束其它來源的輸入可以使用正則表達式和自定義的驗證規則.
拒絕.檢測已知的有害數據輸入并拒絕.
過濾.有時候你會希望過濾掉用戶輸入中那些有安全隱患的那些部分.例如,你的程序允許自由格式的輸入,比如備注字段,你會允許特定的安全HTML標記象<b>,<i>及其它的HTML標記.
步驟提要
通過以下步驟保護你的ASP.NET程序不受注入式攻擊危害 :
第一步.使用ASP.NET請求驗證.
第二步.約束輸入.
第三步.對不安全的輸出進行編碼.
第四步.對SQL查詢語句使用命令參數.
第五步.驗證ASP.NET的出錯信息沒有泄漏至客戶端.
下面的章節將對這些步驟進行詳細討論.
第一步.使用ASP.NET請求驗證.
默認地,ASP.NET 1.1和2.0請求驗證會對送至服務器的數據檢測是否含有HTML標記元素和保留字符.這可以防止用戶向程序中輸入腳本.請求驗證會對照一個有潛在威脅的字符串列表進行匹配,如果發現異常它會拋出一個HttpRequestValidationException類型的異常.
你可以在你的web.config文件中的<pages>元素中加入validateRequest="false" 或在單獨的頁面的@Pages元素里面設置ValidateRequest = "false"來禁用此項功能.
如果你想禁用請求驗證功能,你可以僅在需要的頁面禁用它.比如你在程序頁面上包含一個可接受HTML格式輸入的字段.
確定在Machine.config文件中請求驗證功能被打開.
請求驗證功能在ASP.NET中被默認啟用.你可以在Machine.config.comments文件中看到如下的默認設置.
<pages validateRequest = "true" ... />
確認你沒有修改你的服務器的Machine.config和應用程序的Web.config文件里的默認設置.
測試ASP.NET請求驗證
你可以測試請求驗證的作用.創建一個ASP.NET頁面通過設置ValidateRequest = "fasle"禁用請求驗證,代碼如下 :
<%@ Language="C#" ValidateRequest="false" %>
<html>
<script runat="server">
void btnSubmit_Click(Object sender, EventArgs e)
{
//
If ValidateRequest is false, then ’hello’ is displayed
//
If ValidateRequest is true, then ASP.NET returns an exception
Response.Write(txtString.Text);
}
</script>
<body>
<form id="form1" runat="server">
<asp:TextBox id="txtString" runat="server"
Text="<script>alert(’hello’);</script>" />
<asp:Button id="btnSubmit" runat="server" OnClick="btnSubmit_Click"
Text="Submit" />
</form>
</body>
</html>
當你運行頁面的時候,"Hello"被顯示在一個消息框中,因為在txtString中的腳本被執行并被客戶端的瀏覽器處理.
如果你設置ValidateRequest = "true" 或者移除ValidateRequest頁面屬性,ASP.NET請求驗證會拒絕腳本輸入并拋出一個象下面這樣的錯誤信息.
A potentially dangerous Request.Form value was detected from the client (txtString="<script>alert(’hello").
注意 不要僅僅依賴請求驗證功能,而只是把它作為自定驗證的輔導手段.
第二步.約束輸入
要約束輸入通過如下方法 :
使用服務器端的輸入驗證.不要依賴于客戶端的驗證,因為它很容易就被繞過.使用客戶端驗證是為了減少頁面返住次數提升性能,改進用戶體驗.
驗證輸入的長度,范圍,格式和類型.確保輸入內容是符合要求的正確內容.
使用強數據類型.為數字類型的輸入指定如Integer或者Double的類型.為字符輸入指定為String數據類型.為日期時間輸入指定DateTime類型.
要驗證表單里面的HTML控件輸入字段,在服務器端代碼中進行驗證,使用Regex正則表達式類型可以幫助約束字符輸入.下面的章節介紹如何約束普通輸入類型的變量.
驗證字符串字段
要驗證字符串字段,如姓名,地址,傳真,生份證號碼,使用正則表達式.
約束可接受的字符范圍.
啟動格式規則.例如,基于模式的字段如稅號,郵編,郵遞區號需要規定的字符模式.
驗證長度.
使用正則表達式驗證控件(RegularExpresionValidator)
要使用則表達式驗證控件需要設置待驗證的控件名(ControlToValidate),驗證表達式(ValidationExpression)和出錯提示(ErrorMessage).相關的屬性設置請看下面的代碼示例.
<form id="WebForm" method="post" runat="server">
<asp:TextBox id="txtName" runat="server"></asp:TextBox>
<asp:RegularExpressionValidator id="nameRegex" runat="server"
ControlToValidate="txtName"
ValidationExpression="^[a-zA-Z’.\s]{1,40}$"
ErrorMessage="Invalid name">
</asp:regularexpressionvalidator>
</form>
在上面的代碼中,正則表達式被用于限定輸入的名字為字母(允許大寫字母和小寫字母),空格,單名省略號象O’Dell和句點.此外,輸入的字符長度被限定在40個字符.
注意 正則表達式驗證控件(RegularExpressionValidator)會自動加入脫字符(^)和美元符號($)作為開始和結束的分隔符.如果你沒有在自定義的表達式中加入他們那么最好加入.加入分隔符只是為了讓你的表達式得到想要的那部分數據內容.
文章來源于領測軟件測試網 http://www.kjueaiud.com/