簡單的 web 安全 checklist

weixin_33912445發表於2018-04-10

面向公網的web服務或者http介面服務可能會面臨黑客的攻擊,故一些基本的web安全案例在上線之前要過一遍,本文記錄一些簡單的web安全漏洞,後續發現陸續補充。

1.越權訪問

漏洞場景

類似於http://xxxx.com/resource/:id格式的路由,要特別注意越權訪問的問題

例如http://xxxx.com/resource/123456是屬於使用者A的資源,但是後臺沒有對資源從屬關係做驗證,導致惡意使用者B登入後也可以通過此連結訪問到資源

解決方案

此漏洞比較低階,但是也是一個需要注意的點。 開發類似的資源介面時,注意一下做身份校驗就可以了。

2.伺服器路徑洩露

漏洞場景

有時候服務端對錯誤資訊處理不當,在生產環境中和開發環境一樣,把錯誤的message和呼叫棧同時列印出來,會暴露伺服器內部的路徑。

這樣的漏洞本身不會導致什麼危害,但是若與其他漏洞結合,容易導致黑客推斷出伺服器內部的具體情況,所以一般也會被認為是一種安全漏洞。

解決方案

為生產環境開發一個友好的報錯介面,只顯示錯誤message,不要顯示錯誤資訊堆疊。

3.xss

漏洞場景

富文字 : 含有使用者編輯富文字頁面為xss重災區,是典型的儲存型xss場景。 使用者A編輯了一段含有xss程式碼的內容存放於db,渲染到頁面上展現給其他使用者時,若使用者內容出入時都沒有做好xss過濾的措施,就會導致其他使用者面臨xss攻擊的風險。

頁面直接顯示url引數中的內容

比較典型的例如查詢引數、頁碼引數等。類似於http://xxx.com/xxx/?query=keyword&pageindex=4

若頁面上對keyword或者pageindex處理不當直接渲染在頁面上,則容易導致反射型xss攻擊

解決方案

要注意的一點,現在很多瀏覽器已經可以自動攔截部分xss攻擊程式碼了,但是這並不意味著我們就可以不處理xss,因為不能保證所有使用者都用了先進的瀏覽器。

9476575-2ae4ee80a274ac06.png

在除錯的時候可以給介面加上res.header('X-XSS-Protection' , 0 );這個header來允許瀏覽器執行xss程式碼。

過濾xss的規則比較繁雜,可自行google之。nodejs有一些開源的元件可以很方便的用來處理xss問題,例如:https://github.com/leizongmin/js-xss

4.csrf

漏洞場景

csrf如果不注意防範,很容易被攻擊。

get請求

若使用者的敏感操作是一個get請求,如http://xxxx.com/pay?money=100&to=user,此時攻擊者在釣魚頁面中插入一個img標籤,src的值是http://xxxx.com/pay?money=100&to=attacter。攻擊者將此頁面傳送給網站的使用者,若使用者已經登入,則敏感操作將成功。

post請求

get請求做敏感操作實際上是很低階的錯誤。那麼使用post請求就很安全了嗎? 也不是的,攻擊者可以在釣魚頁面中偽造表單,若xxxx.com使用者已經登入,照樣會被攻擊,像下面的程式碼一樣

使用者進入攻擊頁面後,攻擊者可以自動提交表單,若使用者已經登入了xxxx.com則請求依然會成功

解決方案

檢查referer

檢查下請求的referer,根據地址來判斷是否接受請求

新增csrf token

在cookie中寫入一個隨機生成的csrf token,使用者請求的時候這樣構造表單

這樣攻擊者在偽造表單的時候,是沒辦法獲取csrf token隨機值的——除非網站還有xss漏洞,攻擊者可以拿到使用者的cookie。因此cookie中的csrf token建議是寫成http only的,那樣會更為安全一點。

為了更簡單的處理此類問題,還可以考慮在頁面中使用封裝好的ajax庫,然後在全域性配置的請求header中加上token,後端驗證的時候也從header中去取token。

nodejs+express開發web server的話,可以用一些開源的模組來快速處理此類問題,例如csurf模組:https://github.com/expressjs/csurf

5.sql注入

sql注入的場景比較多,這裡記錄一下我所瞭解到的場景和防範方式吧,後續補充。

漏洞場景

客戶端字元未經處理

這種方式的sql注入在遠古時代的web應用中比較常見,現在的web應用一般不會出現這樣的低階注入問題。

例如select * from table where user='xxxxxxxxx' and password=123456

假如user欄位是直接使用使用者輸入字元做拼接的,那麼可以輸入xxxx' or 1=1 --,來讓sql語句變成:

select*fromtable where user='xxxx'or1=1--' and password=000000`

這樣就可以非法獲取使用者資料了。

bigint注入

參見http://www.vuln.cn/6818

解決方案

首先客戶端填寫的引數是絕對不能未經處理直接拿來拼接sql語句的,如果是手動拼接sql,要注意替換下面這些符號:

sqlValue.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/'/g,"\\\'").replace(/\r/g,"\\r").replace(/\n/g,"\\n")

若不是手動拼接sql而是使用的orm框架,則一般框架會自己去處理sql注入的問題。

而bigint注入,一般容易出現在分頁等場景中,此處要注意的就是pageindex、pagesize、offset等引數一定要做數字型別校驗及大小校驗。

6.上傳檔案型別繞過

漏洞場景

上傳檔案時,需要注意限制使用者上傳的檔案型別,如只接受圖片等。判斷檔案型別的時候,有時候只會去判斷檔案字尾名是否合法,此時會有檔案型別繞過的風險,攻擊者將檔案字尾名修改之後上傳,即可繞過服務端對檔案型別的檢測

解決方案

一般來說不僅僅要檢查檔案字尾名,還需要根據檔案頭的前幾個位元組來判斷檔案的真實型別,對應關係可以參考百度百科:http://baike.baidu.com/item/%E6%96%87%E4%BB%B6%E5%A4%B4

若是nodejs應用,可以用此模組來判斷:https://www.npmjs.com/package/file-type

7.http響應頭注入

漏洞場景

使用者輸入的引數未經處理直接在http的response響應頭中出現,由於http報文是用\r\n來分隔head和body的,攻擊者可能在引數中插入\r\n來截斷原本的報文,構造任意響應body

解決方案

在使用者輸入的響應頭中過濾回車換行符%0d%0a

實際上,引數中包含%00——%1f的控制字元時都是不合法的,可以對其進行刪除

相關文章