2019/3/14 8:48:36
下面給出了五個(gè)例子,闡述如(rú)何按照(zhào)上(shàng)述建議增強應用(yòng)程序的(de)安全性。這些例子示範了代碼中可(kě)能(néng)出現的(de)缺陷,以及它們帶來的(de)安全風險、如(rú)何改寫最少(shǎo)的(de)代碼來有(yǒu)效地(dì)降低攻擊風險。
1 篡改參數
◎ 使用(yòng)ASP.NET域驗證器(qì)
盲目信任用(yòng)戶輸入是保障Web應用(yòng)安全的(de)第一敵人(rén)。用(yòng)戶輸入的(de)主要來源是HTML表單中提交的(de)參數,如(rú)果不能(néng)嚴格地(dì)驗證這些參數的(de)合法性,就有(yǒu)可(kě)能(néng)危及服務器(qì)的(de)安全。
下面的(de)C#代碼查詢後端SQL Server數據庫,假設user和(hé)password變量的(de)值直接取自用(yòng)戶輸入:
SqlDataAdapter my_query = new SqlDataAdapter(
"SELECT * FROM accounts WHERE acc_user='" + user + "' AND acc_password='" + password, the_connection);
從表面上(shàng)看,這幾行(xíng)代碼毫無問題,實際上(shàng)卻可(kě)能(néng)引來SQL注入式攻擊。攻擊者隻要在user輸入域中輸入“OR 1=1”,就可(kě)以順利登錄系統,或者隻要在查詢之後加上(shàng)适當的(de)調用(yòng),就可(kě)以執行(xíng)任意Shell命令:
'; EXEC master..xp_cmdshell(Oshell command here')--
■ 風險分(fēn)析
在編寫這幾行(xíng)代碼時,程序員無意之中作出了這樣的(de)假定:用(yòng)戶的(de)輸入内容隻包含“正常的(de)”數據——合乎人(rén)們通常習(xí)慣的(de)用(yòng)戶名字、密碼,但(dàn)不會(huì)包含引号之類的(de)特殊字符,這正是SQL注入式攻擊能(néng)夠得逞的(de)根本原因。黑(hēi)客們可(kě)以借助一些具有(yǒu)特殊含義的(de)字符改變查詢的(de)本意,進而調用(yòng)任意函數或過程。
■ 解決方案
域驗證器(qì)是一種讓ASP.NET程序員對域的(de)值實施限制(zhì)的(de)機制(zhì),例如(rú),限制(zhì)用(yòng)戶輸入的(de)域值必須匹配特定的(de)表達式。
要防止上(shàng)述攻擊行(xíng)爲得逞,第一種辦法是禁止引号之類的(de)特殊字符輸入,第二種辦法更嚴格,即限定輸入域的(de)内容必須屬于某個(gè)合法字符的(de)集合,例如(rú)“[a-zA-Z0-9]*”。
2 篡改參數之二
◎ 避免驗證操作的(de)漏洞
然而,僅僅爲每個(gè)輸入域引入驗證器(qì)還不能(néng)防範所有(yǒu)通過修改參數實施的(de)攻擊。在執行(xíng)數值範圍檢查之時,還要指定正确的(de)數據類型。
也(yě)就是說,在使用(yòng)ASP.NET的(de)範圍檢查控件(jiàn)時,應當根據輸入域要求的(de)數據類型指定适當的(de)Type屬性,因爲Type的(de)默認值是String。
<!-- 要求輸入值必須是1-9之間的(de)數字 -->
<asp:RangeValidator ... MinimumValue="1" MaximumValue="9" .../>
■ 風險分(fēn)析
由于沒有(yǒu)指定Type屬性值,上(shàng)面的(de)代碼将假定輸入值的(de)類型是String,因此RangeValidator驗證器(qì)隻能(néng)确保字符串由0-9之間的(de)字符開(kāi)始,“0abcd”也(yě)會(huì)被認可(kě)。
■ 解決方案
要确保輸入值确實是整數,正确的(de)辦法是将Type屬性指定爲Integer:
<!-- 要求輸入值必須是1-9之間的(de)數字 -->
<asp:RangeValidator ... MinimumValue="1"
MaximumValue="9" Type="Integer"
3 信息洩漏
◎ 讓隐藏域更加安全
在ASP.NET應用(yòng)中,幾乎所有(yǒu)HTML頁面的(de)__VIEWSTATE隐藏域中都(dōu)可(kě)以找到(dào)有(yǒu)關應用(yòng)的(de)信息。由于__VIEWSTATE是BASE 64編碼的(de),所以常常被忽略,但(dàn)黑(hēi)客可(kě)以方便地(dì)解碼BASE 64數據,用(yòng)不著(zhe)花什(shén)麽力氣就可(kě)以得到(dào)__VIEWSTATE提供的(de)詳細資料。
■ 風險分(fēn)析
默認情況下,__VIEWSTATE數據将包含:
⑴ 來自頁面控件(jiàn)的(de)動态數據。
⑵ 程序員在ViewState中顯式保存的(de)數據。
⑶ 上(shàng)述數據的(de)密碼簽字。
■ 解決方案
設置EnableViewStatMAC="true",啓用(yòng)__VIEWSTATE數據加密功能(néng)。然後,将machineKey驗證類型設置成3DES,要求ASP.NET用(yòng)Triple DES對稱加密算法加密ViewState數據。
4 SQL注入式攻擊
◎ 使用(yòng)SQL參數API
正如(rú)前文(wén)“篡改參數”部分(fēn)描述的(de),攻擊者可(kě)以在輸入域中插入特殊字符,改變SQL查詢的(de)本意,欺騙數據庫服務器(qì)執行(xíng)惡意的(de)查詢。
■ 風險分(fēn)析
惡意查詢有(yǒu)可(kě)能(néng)獲取後端數據庫保存的(de)任何信息,例如(rú)客戶信用(yòng)卡号碼的(de)清單。
■ 解決方案
除了前面介紹的(de)辦法——用(yòng)程序代碼确保輸入内容隻包含有(yǒu)效字符,另一種更加健壯的(de)辦法是使用(yòng)SQL參數API(例如(rú)ADO.NET提供的(de)API),讓編程環境的(de)底層API(而不是程序員)來構造查詢。
使用(yòng)這些API時,程序員或者提供一個(gè)查詢模闆,或者提供一個(gè)存儲過程,然後指定一系列的(de)參數值,由底層API将參數值嵌入到(dào)查詢模闆,然後将構造出來的(de)查詢提交給服務器(qì)查詢。這種辦法的(de)好處是确保參數能(néng)夠正确地(dì)嵌入,例如(rú),系統将對引号進行(xíng)轉義處理(lǐ),從根本上(shàng)杜絕SQL注入式攻擊的(de)發生。同時,在表單中引号仍是一個(gè)允許輸入的(de)有(yǒu)效字符,這也(yě)是使用(yòng)底層API的(de)一個(gè)優點。
按照(zhào)這種思路(lù)修改前文(wén)“篡改參數”部分(fēn)的(de)例子,結果如(rú)下:
深圳市南山區南山街(jiē)道南海(hǎi)大(dà)道西(xī)桂廟路(lù)北陽光(guāng)華藝大(dà)廈1棟4F、4G-04
咨詢電話(huà):136 8237 6272
大(dà)客戶咨詢:139 0290 5075
業(yè)務QQ:195006118
技術(shù)QQ:179981967