吳 全,錢小軍,金 龍
(江蘇金盾檢測技術(shù)有限公司,江蘇 南京 210013)
目前,國內(nèi)的軟件服務(wù)外包行業(yè)發(fā)展迅速,對人才的需求量也急劇攀升,使軟件服務(wù)外包人才供不應(yīng)求,而當(dāng)前高校的教學(xué)內(nèi)容又與企業(yè)的用人需求存在明顯的差距,高校畢業(yè)生無法立即投入工作。國內(nèi)有很多的培訓(xùn)機(jī)構(gòu),他們各有著自己的一套培訓(xùn)流程和教學(xué)方案,水平參差不齊。近年來雖然很多高校為了加強(qiáng)學(xué)生的實(shí)踐編程能力,與這些培訓(xùn)機(jī)構(gòu)合作在教學(xué)大綱中加入了實(shí)踐課程,但是靠著短短幾周的突擊填鴨式教學(xué),所完成的項(xiàng)目多半是不嚴(yán)謹(jǐn)?shù)?,存在著諸多安全問題。不僅是培訓(xùn)機(jī)構(gòu)會(huì)忽視開發(fā)中的安全問題,很多軟件公司的從業(yè)人員也很少考慮過項(xiàng)目的安全性。尤其是在開發(fā)小型系統(tǒng)或者針對內(nèi)網(wǎng)的系統(tǒng)時(shí),為了方便調(diào)試和使用,開發(fā)方和運(yùn)維方都會(huì)忽視應(yīng)用的安全問題。下面我們以Web系統(tǒng)為例,簡略地探討在外包項(xiàng)目中開發(fā)人員很少會(huì)關(guān)注到卻又十分重要的安全問題。
在很多需要權(quán)限分級(jí)管理的系統(tǒng)中,開發(fā)人員在登錄、注冊等頁面里處理用戶的密碼時(shí),通常的做法只是將用來填寫密碼的文本框的type屬性設(shè)置為password,使得密碼字段中的字符通過特殊符號(hào)進(jìn)行替換以達(dá)到隱藏的作用[1]。但在用戶提交信息到服務(wù)器時(shí),卻讓密碼以明文的方式進(jìn)行傳輸??雌饋硎且粋€(gè)很小的問題,但是,在實(shí)際應(yīng)用中,這是個(gè)很大的隱患。很多開發(fā)人員可能也考慮過這個(gè)問題,只是鑒于應(yīng)用用戶較少,而且只能處于內(nèi)網(wǎng)環(huán)境中,就直接忽略了[2]。但是表單中明文傳送密碼,一旦流量被惡意攻擊者嗅探到,就可能產(chǎn)生一定的不良影響。最簡單的解決方式是將密碼通過js加密后再傳遞到后臺(tái),然后控制器在校驗(yàn)密碼時(shí)直接取數(shù)據(jù)庫中的密文進(jìn)行匹配[3]。
這個(gè)問題可能出現(xiàn)在密碼校驗(yàn)邏輯中:校驗(yàn)結(jié)果的不同分支,返回給頁面提示信息不同,密碼錯(cuò)誤和用戶名不存在是兩個(gè)不同分支中的。這樣一來,居心叵測者就可能通過多次輸入并提交而猜中系統(tǒng)中可能存在的用戶名。同時(shí),攻擊者還可以暴力枚舉來嘗試獲得用戶的密碼,如果用戶的密碼強(qiáng)度較為脆弱,很容易被攻擊者枚舉出密碼[4]。因此,對于用戶的操作需要作出跟蹤限制,對于可能是非法操作的用戶,暫停對其的服務(wù);或者在提交數(shù)據(jù)時(shí)加上驗(yàn)證碼等防止自動(dòng)化攻擊的方式,這樣加大攻擊者的攻擊成本來進(jìn)行防御,同時(shí)對用戶的使用影響可以降到最低。
“永遠(yuǎn)不要相信用戶的輸入”是對設(shè)計(jì)人員和編碼人員說的,是進(jìn)行安全設(shè)計(jì)和安全編碼的重要準(zhǔn)則。換一句話來說,就是用戶在任何時(shí)候所輸入的數(shù)據(jù)在證明其無害之前,都是有害的。許多危險(xiǎn)的漏洞就是因?yàn)檫^于相信用戶的輸入是善意的而導(dǎo)致的。而很多不成熟、速成的開發(fā)者,只關(guān)注功能上的實(shí)現(xiàn),很容易忽視對用戶的輸入的檢查。有些開發(fā)者在前端頁面上使用js對用戶的輸入進(jìn)行限制,將數(shù)據(jù)通過POST方法提交后便覺得高枕無憂,在后端便放松了對用戶輸入數(shù)據(jù)的檢查,認(rèn)為傳遞來的參數(shù)一定是符合設(shè)計(jì)規(guī)則的。然而,攻擊者可以使用burpsuite和fiddler等代理工具,對數(shù)據(jù)包中的數(shù)據(jù)進(jìn)行修改。這時(shí)候,如果后端的程序沒有對用戶輸入數(shù)據(jù)進(jìn)行檢查,這樣的惡意數(shù)據(jù)如果傳遞到拼接的sql語句中,就可能會(huì)造成sql注入漏洞;如果被顯示在頁面上,可能造成跨站腳本攻擊漏洞等。項(xiàng)目的開發(fā)一般是由團(tuán)隊(duì)完成的,稍微復(fù)雜一些的項(xiàng)目,更會(huì)有數(shù)不清的用戶輸入點(diǎn),一旦其中的一個(gè)輸入點(diǎn)沒有對用戶輸入進(jìn)行檢查,便有可能對整個(gè)系統(tǒng)的產(chǎn)生威脅。
有些開發(fā)人員會(huì)說對輸入數(shù)據(jù)進(jìn)行如此多的檢查會(huì)影響性能,實(shí)際上,大多數(shù)輸入檢查并不對性能造成大的損害,即使有損害,一個(gè)稍慢但是相對安全的系統(tǒng)也比一個(gè)快速但容易受到攻擊的系統(tǒng)要好。如果客戶對你的系統(tǒng)性能不滿意,應(yīng)尋找其他途徑提高性能,不要通過減少安全檢查來提高性能,因?yàn)楫?dāng)客戶的系統(tǒng)因漏洞被攻破以后,你面臨的就不是幾句抱怨,而是一場災(zāi)難了。正確的做法是在客戶端和服務(wù)端都作相同的檢查,客戶端的檢查的目的是為了界面的友好、節(jié)省用戶的時(shí)間,服務(wù)端的檢查才是為了數(shù)據(jù)的完整和安全。
一些Web應(yīng)用的404、500頁面使用的是容器默認(rèn)的頁面,而有些默認(rèn)報(bào)錯(cuò)頁面不僅對用戶不友好,還會(huì)造成服務(wù)器敏感信息的泄露[5]。增強(qiáng)安全意識(shí),應(yīng)該避免使用服務(wù)器默認(rèn)的錯(cuò)誤頁面信息。
很多網(wǎng)站管理維護(hù)人員,為了維護(hù)網(wǎng)站時(shí)的便利,會(huì)在服務(wù)器上留下有規(guī)律的備份文件。這些文件如果被攻擊者枚舉猜測到,便會(huì)造成不同程度的安全威脅[6]。
近年來隨著版本控制系統(tǒng)的流行,很多團(tuán)隊(duì)在結(jié)束開發(fā)時(shí)會(huì)忘記刪除版本控制系統(tǒng)的目錄,比如.git,.svn目錄,這種項(xiàng)目部署后可能會(huì)造成網(wǎng)站應(yīng)用代碼泄露的風(fēng)險(xiǎn)。此外,開發(fā)人員在使用版本控制系統(tǒng)時(shí)可能會(huì)將代碼同步到公開的平臺(tái)上,在這一過程中會(huì)將開發(fā)或者生產(chǎn)環(huán)境中的配置文件里可能存在的敏感信息刪除,便會(huì)導(dǎo)致攻擊者通過公開在平臺(tái)里的項(xiàng)目獲取到敏感信息[7]。
目錄遍歷漏洞指通過在URL或參數(shù)中構(gòu)造 ../,./ 和類似的跨父目錄字符串的ASCII 編碼、unicode 編碼等,完成目錄跳轉(zhuǎn),讀取操作系統(tǒng)各個(gè)目錄下的敏感文件,也可以稱作“任意文件讀取漏洞”[8]。
目錄遍歷漏洞原理從根本上來說還是因?yàn)殚_發(fā)人員在編寫程序時(shí)沒有充分檢查用戶的輸入,沒有過濾用戶輸入的../ 之類的目錄跳轉(zhuǎn)符,導(dǎo)致用戶可以通過提交目錄跳轉(zhuǎn)來遍歷服務(wù)器上的任意文件。使用多個(gè).. 符號(hào),不斷向上跳轉(zhuǎn),最終停留在根 /,通過絕對路徑去讀取任意文件。因此,更應(yīng)當(dāng)針對不同功能時(shí)刻注意檢查用戶的輸入。
此外,對于nginx等HTTP和反向代理服務(wù)器的配置失誤,也可能造成目錄遍歷漏洞。
例如,在nginx的網(wǎng)站配置中,使用如下的配置:
location /xxxx {
alias /var/www/html/xxxx/;
}
location /admin {
alias /var/www/html/admin/;
}
location沒限制后面,那/admin./就會(huì)被好心的nginx處理成/admin/./,同理/admin../就會(huì)被nginx處理成/admin/../,便可能將網(wǎng)站根目錄里的信息通過nginx的Directory list列出來。
CSRF(Cross-Site Request Forgery),中文名稱即為“跨站請求偽造攻擊”。攻擊者可以盜用用戶的登錄信息,以用戶的身份模擬發(fā)送各種請求[9]。攻擊者只要借助少許的社會(huì)工程學(xué)的詭計(jì),例如通過QQ等聊天軟件發(fā)送的鏈接(有些還偽裝成短域名,用戶無法分辨),攻擊者就能迫使Web應(yīng)用的用戶去執(zhí)行攻擊者預(yù)設(shè)的操作。例如,當(dāng)用戶登錄網(wǎng)絡(luò)銀行去查看其存款余額,在他沒有退出時(shí),就點(diǎn)擊了一個(gè)QQ好友發(fā)來的鏈接,那么該用戶銀行賬戶中的資金就有可能被轉(zhuǎn)移到攻擊者指定的賬戶中。所以遇到CSRF攻擊時(shí),將對終端用戶的數(shù)據(jù)和操作指令構(gòu)成嚴(yán)重的威脅。當(dāng)受攻擊的終端用戶具有管理員賬戶的時(shí)候,CSRF攻擊將危及整個(gè)Web應(yīng)用程序。
CSRF的防御可以從服務(wù)端和客戶端兩方面著手,從服務(wù)端著手的防御效果比較好的,現(xiàn)在一般的CSRF防御也都在服務(wù)端進(jìn)行。服務(wù)端的預(yù)防CSRF攻擊的方式方法有多種,但思路上都是差不多的,主要從兩方面入手,一方面是正確使用GET,POST請求和cookie,另一方面是在非GET請求中增加token。
一般而言,普通的Web應(yīng)用都是以GET和POST請求為主,還有一種請求是cookie方式。在常規(guī)的開發(fā)模式中,GET請求常用在查看、列舉、展示等不需要改變資源屬性的時(shí)候;POST請求常用在表單提交,改變一個(gè)資源的屬性或者做其他一些事情的時(shí)候。
當(dāng)正確地使用了GET和POST請求之后,剩下的就是在非GET方式的請求中增加隨機(jī)數(shù),主要通過3種方式來進(jìn)行:(1)要為每個(gè)用戶生成一個(gè)唯一的cookie token,所有表單都包含同一個(gè)偽隨機(jī)值,這種方案最簡單,因?yàn)槔碚撋瞎粽卟荒塬@得第三方的cookie。(2)讓每個(gè)POST請求使用驗(yàn)證碼,這個(gè)方案算是比較完美的,但是需要用戶多次輸入驗(yàn)證碼,用戶體驗(yàn)比較差,所以不適合在業(yè)務(wù)中大量運(yùn)用。(3)在渲染表單的時(shí)候,為每一個(gè)表單包含一個(gè)csrf Token,提交表單的時(shí)候,帶上csrf Token,然后在后端做csrf Token驗(yàn)證[10]。
隨著B/S架構(gòu)的Web應(yīng)用飛速發(fā)展,其帶來的安全威脅也與日俱增,深深地影響到人們的生活。作為計(jì)算機(jī)軟件系統(tǒng)的開發(fā)、維護(hù)人員,更應(yīng)當(dāng)注意到網(wǎng)絡(luò)安全的重要性。本文通過對一些容易被忽視的安全問題進(jìn)行了深入全面的分析,希望能為一些安全意識(shí)淡薄的開發(fā)編碼人員帶來一些安全開發(fā)上應(yīng)考慮的問題和建議。