常見的 Web 攻擊與防范
今天我們來(lái)聊一聊常見的 Web 安全相關(guān)的問(wèn)題,也會(huì)在接下來(lái)的一節(jié)中說(shuō)一說(shuō) Django 在 Web 安全方面做了哪些工作。了解了這些才有可能防范出現(xiàn)一些低級(jí)的安全問(wèn)題,避免給開發(fā)的項(xiàng)目留下十分明顯的安全隱患。當(dāng)然,完美的應(yīng)用肯定是不存在的,都會(huì)有未被發(fā)現(xiàn)的漏洞,我們?cè)陂_發(fā)中只需要保證不要出現(xiàn)太過(guò)于明顯的問(wèn)題即可。
1. DDoS攻擊
全稱 Distributed Denial of Service,中文意思為“分布式拒絕服務(wù)”,就是利用大量合法的分布式服務(wù)器對(duì)目標(biāo)發(fā)送請(qǐng)求,從而導(dǎo)致正常合法用戶無(wú)法獲得服務(wù)。DDoS 攻擊方式簡(jiǎn)單粗暴,可以達(dá)到直接摧毀目標(biāo)的目的。
另外,相對(duì)其他攻擊手段 DDoS 的技術(shù)要求和發(fā)動(dòng)攻擊的成本很低,只需要購(gòu)買部分服務(wù)器權(quán)限或通過(guò)技術(shù)手段控制一批肉雞即可。另一方面,DDoS 具有攻擊易防守難的特征,服務(wù)提供商為了保證正常客戶的需求需要耗費(fèi)大量的資源才能和攻擊發(fā)起方進(jìn)行對(duì)抗。這些特點(diǎn)使得 DDoS 成為黑客們手中的一把很好使的利劍,而且所向披靡。
DDos 的攻擊形式多種多樣,有針對(duì)資源消耗類攻擊、服務(wù)消耗性攻擊、反射性攻擊、混合型攻擊等等,最終達(dá)到對(duì)端服務(wù)不可用的目的。
互聯(lián)網(wǎng)發(fā)展至今,DDoS 攻擊就一直存在,而且隨著技術(shù)的發(fā)展,DDoS 的攻擊方式也變化多端。目前而言,對(duì)于 DDoS 攻擊仍舊是一個(gè)令人頭疼的問(wèn)題,許多創(chuàng)業(yè)公司或者規(guī)模較小的公司,不愿過(guò)多投入到防御體系的建設(shè)上,這就導(dǎo)致大部分公司面對(duì)高流量的 DDoS 攻擊時(shí)都是直接投降,毫無(wú)還手之力。
目前,安全產(chǎn)業(yè)對(duì) DDoS 的防護(hù)系統(tǒng)本質(zhì)上是一個(gè)基于資源較量和規(guī)則過(guò)濾的智能化系統(tǒng),主要的防御手段和策略包括:
- 資源隔離
- 用戶規(guī)則
- 大數(shù)據(jù)智能分析
- 資源對(duì)抗
隨著目前人工智能和深度學(xué)習(xí)技術(shù)的火熱發(fā)展,在 Web 安全領(lǐng)域已經(jīng)開展了許多關(guān)于這方面的實(shí)踐研究,也相信不久的將來(lái),DDoS 攻擊能徹底被深度學(xué)習(xí)技術(shù)打敗,不再成為大部分業(yè)內(nèi)公司的噩夢(mèng)。
2. CSRF攻擊
CSRF(Cross-site request forgery),中文名稱:跨站請(qǐng)求偽造。可以這么簡(jiǎn)單理解CSRF攻擊:攻擊者盜用了你的身份(獲取登錄正規(guī)網(wǎng)站的 cookie 信息), 并以你的名義發(fā)送惡意請(qǐng)求(比如轉(zhuǎn)賬、提交訂單等)。CSRF 主要會(huì)導(dǎo)致個(gè)人的隱私泄露并威脅財(cái)產(chǎn)安全。我們用下面一幅圖來(lái)描述一下 CSRF 攻擊的形成與危害:
從上面的示例過(guò)程可以看出,要完成一次 CSRF 攻擊,受害者必須依次完成兩個(gè)步驟:
- 登錄受信任網(wǎng)站A,并在本地生成Cookie;
- 在不登出A的情況下,訪問(wèn)危險(xiǎn)網(wǎng)站B;
上面這幾種情況看似很難一起發(fā)生,但在現(xiàn)實(shí)場(chǎng)景中卻是很容易發(fā)生的。這主要是基于以下幾個(gè)原因?qū)е碌模?/p>
-
我們往往登錄了一個(gè)網(wǎng)站后,打開多個(gè) tab 頁(yè)面去訪問(wèn)多個(gè)其他網(wǎng)站,類似于下圖:
-
關(guān)閉瀏覽器了后,本地的 Cookie 并不會(huì)立即過(guò)期,上次會(huì)話也并不意味著結(jié)束,除非我們點(diǎn)擊登出(logout)或者主動(dòng)清除瀏覽器緩存;
-
所謂的危險(xiǎn)網(wǎng)站,可能是經(jīng)常被人訪問(wèn)的正規(guī)網(wǎng)站。該網(wǎng)站由于存在某種漏洞被人惡意攻擊,并在網(wǎng)站中放入惡意鏈接誘導(dǎo)用戶點(diǎn)擊;
基于以上三點(diǎn),CSRF 攻擊很可能每天在我們身邊上演。但是網(wǎng)站必須要確保不存在相應(yīng)的 CSRF 漏洞,否則極容易黑客攻擊。
關(guān)于 CSRF 攻擊的主要防御手段便是在網(wǎng)頁(yè)上添加一個(gè)隨機(jī)的校驗(yàn) token 值。由于 CSRF 的本質(zhì)在于攻擊者欺騙用戶去訪問(wèn)自己設(shè)置的地址,所以如果要求在訪問(wèn)敏感數(shù)據(jù)請(qǐng)求時(shí),要求用戶瀏覽器提供不保存在 cookie 中,并且攻擊者無(wú)法偽造的數(shù)據(jù)作為校驗(yàn),那么攻擊者就無(wú)法再執(zhí)行 CSRF 攻擊。這種數(shù)據(jù)通常是表單中的一個(gè)數(shù)據(jù)項(xiàng)。服務(wù)器將其生成并附加在表單中,其內(nèi)容是一個(gè)偽亂數(shù)。當(dāng)客戶端通過(guò)表單提交請(qǐng)求時(shí),這個(gè)偽亂數(shù)也一并提交上去以供校驗(yàn)。正常的訪問(wèn)時(shí),客戶端瀏覽器能夠正確得到并傳回這個(gè)偽亂數(shù),而通過(guò) CSRF 傳來(lái)的欺騙性攻擊中,攻擊者無(wú)從事先得知這個(gè)偽亂數(shù)的值,服務(wù)器端就會(huì)因?yàn)樾r?yàn) token 的值為空或者錯(cuò)誤,并拒絕這個(gè)可疑請(qǐng)求。
3. XSS攻擊
XSS 攻擊又稱 CSS,全稱Cross Site Script (跨站腳本攻擊),其原理是攻擊者向有 XSS 漏洞的網(wǎng)站中輸入惡意的 HTML 代碼,當(dāng)用戶瀏覽該網(wǎng)站時(shí),這段 HTML 代碼會(huì)自動(dòng)執(zhí)行,從而達(dá)到攻擊的目的。
XSS 攻擊可以分成兩種類型:
- 非持久型 XSS 攻擊:顧名思義,非持久型 XSS 攻擊是一次性的,僅對(duì)當(dāng)次的頁(yè)面訪問(wèn)產(chǎn)生影響。非持久型 XSS 攻擊要求用戶訪問(wèn)一個(gè)被攻擊者篡改后的鏈接,用戶訪問(wèn)該鏈接時(shí),被植入的攻擊腳本被用戶游覽器執(zhí)行,從而達(dá)到攻擊目的;
- 持久型 XSS 攻擊:持久型 XSS,會(huì)把攻擊者的惡意代碼數(shù)據(jù)存儲(chǔ)在服務(wù)器端,攻擊行為將伴隨著惡意代碼的存在而一直存在。
XSS 的攻擊防范主要是對(duì)提交的各種字符串?dāng)?shù)據(jù)進(jìn)行校驗(yàn),避免出現(xiàn)可執(zhí)行的前端代碼。主要的防范措施有:
- 對(duì)輸入內(nèi)容的特定字符進(jìn)行編碼,例如表示 html 標(biāo)記的 < > 等符號(hào);
- 對(duì)重要的 cookie 設(shè)置 httpOnly,防止客戶端通過(guò)
document.cookie
讀取 cookie,此 HTTP 頭在服務(wù)端設(shè)置; - 將不可信的值輸出 URL 參數(shù)之前,進(jìn)行 URLEncode 操作,而對(duì)于從 URL 參數(shù)中獲取值一定要進(jìn)行格式校驗(yàn);
- 不要使用
eval
來(lái)解析并運(yùn)行不確定的數(shù)據(jù)或代碼,對(duì)于 JSON 解析可使用JSON.parse()
方法; - 后端接口也要對(duì)關(guān)鍵的字符進(jìn)行過(guò)濾,防止將惡意的腳本代碼保存到數(shù)據(jù)庫(kù)中。
4. SQL注入攻擊
SQL 注入是網(wǎng)站存在最多也是最簡(jiǎn)單的漏洞,主要原因是程序員在開發(fā)用戶和數(shù)據(jù)庫(kù)交互的系統(tǒng)時(shí)沒(méi)有對(duì)用戶輸入的字符串進(jìn)行過(guò)濾,轉(zhuǎn)義,限制或處理不嚴(yán)謹(jǐn),導(dǎo)致用戶可以通過(guò)輸入精心構(gòu)造的字符串去非法獲取到數(shù)據(jù)庫(kù)中的數(shù)據(jù)。SQL 注入是一種注入攻擊,可以執(zhí)行惡意 SQL 語(yǔ)句。它通過(guò)將任意 SQL 代碼插入數(shù)據(jù)庫(kù)查詢,使攻擊者能夠完全控制 Web 應(yīng)用程序后面的數(shù)據(jù)庫(kù)服務(wù)器。攻擊者可以使用 SQL 注入漏洞繞過(guò)應(yīng)用程序安全措施;可以繞過(guò)網(wǎng)頁(yè)或 Web 應(yīng)用程序的身份驗(yàn)證和授權(quán),并檢索整個(gè) SQL 數(shù)據(jù)庫(kù)的內(nèi)容;還可以使用 SQL 注入來(lái)添加,修改和刪除數(shù)據(jù)庫(kù)中的記錄。有一個(gè)經(jīng)典的例子如下:
一個(gè)網(wǎng)站后臺(tái)管理系統(tǒng)存在 SQL 注入漏洞。它使用 url 傳遞的參數(shù) username 和 password 去數(shù)據(jù)庫(kù)校驗(yàn)對(duì)應(yīng)的用戶名和密碼是否正確,形成的 SQL 語(yǔ)句如下:
SELECT * FROM user WHERE username='admin' AND password='passwd'
如果后臺(tái)服務(wù)對(duì)輸入的用戶名和密碼做任何處理,前臺(tái)直接構(gòu)造用戶名為:’ or 1=1#。此時(shí)后臺(tái)形成的查詢 SQL 語(yǔ)句為:
SELECT * FROM user WHERE username='' or 1=1#' AND password='xxx'
這條語(yǔ)句也是可以執(zhí)行的,而且可以得到所有的用戶記錄。因?yàn)?“or 1” 讓 SQL 的查詢條件永遠(yuǎn)為 True,而 ‘#’ 屏蔽了后面的密碼校驗(yàn)。
早期這種后臺(tái)管理系統(tǒng)的漏洞屢見不鮮。很多人只需要通過(guò)黑客工具找到存在 SQL 注入漏洞的后臺(tái)管理系統(tǒng),然后使用這個(gè)萬(wàn)能密碼就能直接進(jìn)入網(wǎng)站的管理系統(tǒng)頁(yè)面,達(dá)到入侵的目的。
SQL 注入攻擊方式主要有以下三種:
- 帶內(nèi)注入:攻擊者可以通過(guò)相同的通信通道發(fā)起攻擊并獲得結(jié)果,主要通過(guò)以下兩種方式完成。
- 基于錯(cuò)誤的SQL注入:從顯示的錯(cuò)誤消息中獲取有關(guān)數(shù)據(jù)庫(kù)的信息
- 基于聯(lián)合的SQL注入:依賴于攻擊者能夠?qū)NION ALL被盜信息的結(jié)果與合法結(jié)果連接起來(lái)
- 盲注入:也稱為推理SQL注入;
- 帶外注入:攻擊者通過(guò)精心制作的 SQL 語(yǔ)句注入到數(shù)據(jù)庫(kù),可以觸發(fā)數(shù)據(jù)庫(kù)系統(tǒng)創(chuàng)建與攻擊者控制的外部服務(wù)器的連接。通過(guò)這種方式,攻擊者可以收集數(shù)據(jù)或可能控制數(shù)據(jù)庫(kù)的行為。
對(duì)于 SQL 的注入攻擊,在開發(fā) Web 系統(tǒng)時(shí)只需要遵循以下幾點(diǎn)建議,就能避免絕大部分的 SQL 注入漏洞了:
- 避免將用戶提供的輸入直接放入 SQL 語(yǔ)句中,最好使用準(zhǔn)備好的語(yǔ)句和參數(shù)化查詢;
- 不要將敏感數(shù)據(jù)保留在純文本中;
- 限制數(shù)據(jù)庫(kù)權(quán)限和特權(quán);
- 避免直接向用戶顯示數(shù)據(jù)庫(kù)錯(cuò)誤。大部分的時(shí)候,我們需要攔截相關(guān)異常,然后定制化輸出數(shù)據(jù)庫(kù)異常信息;
- 對(duì)訪問(wèn)數(shù)據(jù)庫(kù)的Web應(yīng)用程序使用Web應(yīng)用程序防火墻(WAF);
- 及時(shí)更新數(shù)據(jù)庫(kù)至最新版,防止黑客利用舊版本漏洞發(fā)起攻擊。
5. 小結(jié)
本小節(jié)中我們?cè)敿?xì)介紹了 Web 攻擊的幾種常見方式以及相應(yīng)的防范手段。服務(wù)器上任何一個(gè)應(yīng)用的漏洞都有可能是黑客攻陷服務(wù)器的突破口。筆者之前在公司內(nèi)部部署 saltstack 運(yùn)維管理系統(tǒng)時(shí),不小心讓 saltstack 中的 API 服務(wù)也對(duì)外可訪問(wèn)(服務(wù)啟動(dòng)以 0.0.0.0 的方式),而由于 saltstack 自身的漏洞原因?qū)е卤蝗藪呙璨⒔柚摲?wù)向服務(wù)器內(nèi)部植入了病毒,導(dǎo)致我們主機(jī)卡頓、并被病毒占用大量帶寬,對(duì)外發(fā)送數(shù)據(jù)。最后不得已,只能重裝系統(tǒng),浪費(fèi)了幾天時(shí)間在重裝所有應(yīng)用和服務(wù)上,教訓(xùn)慘痛,當(dāng)切記切記!