編寫安全的ASP代碼

來源:互聯網
上載者:User
安全|安全 ASP中資料庫的安全是一個很嚴肅的問題。很多代碼的編寫者意識到了這類問題,並且小心翼翼地對他們認為有問題的地方做了補救,但常見的情況是要麼沒有窮盡所有的可疑地點,要麼這種補救邏輯上有誤。對於一個耐心且嗅覺靈敏的攻擊者來說,這種意義上的補救措施和沒有任何補救措施沒有本質上區別。
    下面羅列的是一些可能出現的問題:有些是常見易犯的錯誤,有些根本就是邏輯上有問題。看看你是不是也這樣寫過?對於攻擊者而言,倒著看這些東西,應該對尋找漏洞有點協助,更為完整一點的檢測方法,請等我的關於黑/白盒分析和自動化測試文章。

一、令人疑惑的過濾方式
    典型例子是不管不顧地對所有的輸入變數都去掉單引號,或者是把單引號替換成合法的兩個單引號,例如:

id = replace(request.querystring("id"), "'", "")    str = replace(request("someinput"), "'", "''")


    現在很明了的是,第一個做法很有可能是錯誤的。因為引起SQL Injection的不總是單引號,再擴大一點,引起問題的不是任何單獨的符號,這樣子的過濾,有些冤枉單引號了。正確的利用注入,重要的一點是閉合前面的一句SQL查詢語句——往往是得先正確地閉合前面一個條件,因為我們可能會在同一句裡面引入新的條件,補救措施只要破壞注入條件應該就可以了,但是考慮到其複雜性(下面會說),最好還是較為完整的限制一下輸入的字元種類。
    第二個看起來是沒有什麼問題的,但潛在的會帶來一些隱患。這很容易給人造成的一個錯覺是,我對輸入的字串已經很有效做過處理了,以後使用沒有什麼問題。這句話沒有錯,對字串來說這樣做也是很正確的,但是他扮演了一個不光彩的角色,試想一下,如果過濾後的字串放進了資料庫,而後續的語句有直接拿出來使用的,這種對前面過濾的依賴性,是不是正確的呢?
    也許較好的做法應該是,針對具體的情況來確定過濾的準則。
    常見的輸入變數有三種:數字,字串還有集合。對於數字型的輸入變數,簡單調用一下判斷函數即可,見得到的代碼中,凡是檢查了這類變數的,幾乎都正確。對於字串型的來說,基本上在插入到產生的SQL語句時,前後都有單引號,如果僅從破壞注入條件來看,把單引號替換成兩個單引號應該問題不大。同理的,如果是一個字串的集合,也可以簡單的用這種方法。而如果是數位集合,情況可能稍微麻煩一點,至少你得允許數字、逗號或許還有空格之類的符號在輸入中正常出現,這樣子的過濾規則可能顯得複雜,不過你可以借鑒一下dvBBS6.1打過補丁後的版本,總的來說,對於已經發現的過濾漏洞而言,他們還是補得比較好的。
    對於第二句話,至少現在不能說它說錯的,我們留待後面解決。

二、擷取的資料值得信賴嗎?
    其實這樣子說範圍顯得有點大,一下子涉及到很多方面,一個例子一個例子地舉來看好了。
    首先是關於選擇過濾資料的問題。一直以來,我們認為凡是使用者輸入的東西,都要經過適當的處理。沒錯,但真正的是否都做到呢?隨便找個抓包的工具,比如Ethereal,看看在你用IE提交表單或者是開啟串連的時候,都提交了什麼。或者,簡單一些,開啟NetAnt編輯一個任務,在協議標籤中,看看那個“自訂提交者”和“使用者代理程式”的選項。
    我想你已經明白了,對方可以自己定製的東西不僅僅是GET或POST過來的資料!如果所有的使用者都規規矩矩地用瀏覽器,確實不用防備這麼嚴,如果對方不這麼老實,在取服務端變數或Cookie的時候可要小心了,沒有任何人能夠保證你獲得的資料是合法的。對於Cookie而言,很多程式都出過問題,所以以前強調得比較多,至於另外的,關注的人可能比較少一點,但你是否看過或者寫過這樣的代碼:

sql="ShowHOT_COM_inst_online_char 2,"&statuserid&",'"&membername&"','"&memberclass&"','"&Request.ServerVariables("REMOTE_HOST")&"',"&boardid&",'"&Request.ServerVariables("HTTP_USER_AGENT")&"','"&replace(stats,"'","")&"','"&Request.ServerVariables("HTTP_X_FORWARDED_FOR")&"',"&UserGroupID&",'"&actCome&"',"&userhidden&","&userid&""


    Request.ServerVariables("HTTP_USER_AGENT")就是你在NetAnt中看到的使用者代理程式選項,也就是說你可以偽造,同樣可以偽造的還有Request.ServerVariables("HTTP_REFERER"),也就是你在NetAnt中看到的提交者選項等等。在做一些項目的時候,很有可能要將這一類的變數添加入資料庫,這時候要千萬小心,這個地方的忽略,引起的後果和其他類型變數未過濾導致的後果是一樣的。
    在Google上搜尋Referer和Request.ServerVariables兩個關鍵字,還可以看到很多有問題的寫法,或者去看看五月份左右的關於動網論壇入侵的文章,也許你的理解會更加深刻一點。
    然後是一個隱藏得稍微深一點的問題,不是使用者的直接輸入要不要過濾?
    這就回到了我們前面留下的那個問題,單引號換成兩個單引號的潛在威脅。在第二次構造SQL語句的時候,倘若資料是從資料庫裡面直接去取出來用的,多數情況下人們會認為前面已經處理過的東西看起來似乎並沒有必要再處理,或者乾脆就是沒有意識到應該處理。這是極其錯誤的!從兩個方面來看,首先你入庫的時候對提交資料中的單引號處理,僅僅是保證了單次SQL語句構造的正確性,並沒有一勞永逸地解決問題;再說了,後面取出資料用的時候,對資料安全性檢查的依賴並沒有得到保證,因為這種依賴關係沒有傳遞下來,而且依賴關係本身還不是可傳的。
    就replace(request("someinput"), "'", "''")而言,它的不安定性在於這種過濾方式只是一種妥協,換句話說只是在有限的範圍內掩蓋了可能出現的問題,而沒有永久性的處理掉。它還有一個討厭的地方在於給人一種錯覺,似乎是處理過的資料已經安全了,容易讓後繼的代碼編寫者產生虛幻的安全感。對這兩個弱點,不是靠換一個寫法就能解決的,因為如果你把單引號乾脆去掉,又會引來另外一個問題,輸入資料中確實有需要而且正確的單引號怎麼辦?從一開始我就說,單引號本身是無罪的,過濾它只是一種解決手段而已,所以我們還是就這樣寫吧,不過要在後繼的部分加強一下檢查。
    這一類的問題,如果依然用動網論壇做例子,我建議看一下六月八號的漏洞文章。
    還有就是過濾器的位置,這個摻雜了邏輯問題在內的複雜問題。
    我曾經非常驚奇地發現喬客論壇對外散布的版本中一段讓人覺得不可思議的問題代碼,如果你比較感興趣的話,翻翻gallery.asp就能看到一個特定的動作序列(action=flash_view),繞過了所有對id的檢查。
    其實說起來,這一類代碼不太可能有太複雜的邏輯結構,對代碼進行審查的時候,進行所有的分支覆蓋是可以手工完成的,只要稍微想想就會發現對變數的檢查是否能夠有效地到達你的目的地——產生SQL語句的地方。
    關於過濾器的位置,如果要深入下去,馬上就會出來一些讓人眼花繚亂的東西,中間的分析很麻煩而且很形式化,雖然確實有演算法可以保證位置選取的正確性,但是我想這裡還是給出一些結論性的東西吧。倘若你很有興趣,我想你可以來信和我交流。
    過濾的位置,取決於兩個方面:你獲得變數的來源,以及你需要保證到的產生SQL語句的位置。前面一個,不論是來自於直接還是間接輸入,先想想可能的輸入字元;對於後面一個,你要保證無論程式運行情況怎樣,經過了過濾語句的流程一定會經過你需要保證到的產生SQL語句的位置(保證其是有效過濾語句的後向必經節點)。如果你不很清楚流程的判斷,我的建議是if中僅僅判斷,if嵌套間不要有多餘的東西,過濾語句後緊接產生SQL語句。
    再回到前面提到的潛在問題,我們終於可以在這裡解決了:在取出資料後依然首先進行判斷。因為根據前面說的,這一種間接輸入依然有可能出現危險。
    說到這裡,插一句另類的過濾位置問題:不要把對輸入的過濾放到用戶端解決,那是可以繞過的!誰能保證你的VBScript/JavaScript能起作用,如果別人直接用NC或者一個不支援指令碼的瀏覽器呢?
    上述兩個大的方面,以軟體測試的目光來認識,顯然是沒有窮盡所有的分支所導致。在使用對方提交的資料之前,先做一個對方所有可能進入字元的分析列表,然後就每一種輸入分支情況進行類型的審核,這是每個代碼編寫者都應該做的事情。這是一件很簡單的事情,因為只是類型上的審核還好,碰上語義的問題就麻煩了……

三、類型正確意味著允許存取?
    
    涉及到語義的問題,要是可能的話,我選擇最好還是避開。
    譬如對於一個整型數字,你輸入的確實是一個整型,通過了過濾器,潛在的問題是你的輸入內容上合法嗎,或者根本就不應該從你這裡獲得資訊?很多年前就有人提出來,有些註冊的模組存在問題:它裡面的id是通過一個type=hidden掩蓋後隱式提交的,但是我在第一步建立了使用者,第二步仍就有可能通過提交內容不合法的id來修改他人的資訊。這種異類的問題都是非常難發現,而且幾乎都只有靠經驗而不是某一個具體的演算法來處理。我們



相關文章

Cloud Intelligence Leading the Digital Future

Alibaba Cloud ACtivate Online Conference, Nov. 20th & 21st, 2019 (UTC+08)

Register Now >

Starter Package

SSD Cloud server and data transfer for only $2.50 a month

Get Started >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。