當前位置:
首頁 > 知識 > 常見 Web 安全攻防總結

常見 Web 安全攻防總結

Web 安全的對於 Web 從業人員來說是一個非常重要的課題,所以在這裡總結一下 Web 相關的安全攻防知識,希望以後不要再踩雷,也希望對看到這篇文章的同學有所幫助。今天這邊文章主要的內容就是分析幾種常見的攻擊的類型以及防禦的方法。

也許你對所有的安全問題都有一定的認識,但最主要的還是在編碼設計的過程中時刻繃緊安全那根弦,需要反覆推敲每個實現細節,安全無小事。

本文代碼 Demo 都是基於 Node.js 講解,其他服務端語言同樣可以參考。


XSS

首先說下最常見的 XSS 漏洞,XSS (Cross Site Script),跨站腳本攻擊,因為縮寫和 CSS (Cascading Style Sheets) 重疊,所以只能叫 XSS。

XSS 的原理是惡意攻擊者往 Web 頁面里插入惡意可執行網頁腳本代碼,當用戶瀏覽該頁之時,嵌入其中 Web 裡面的腳本代碼會被執行,從而可以達到攻擊者盜取用戶信息或其他侵犯用戶安全隱私的目的。XSS 的攻擊方式千變萬化,但還是可以大致細分為幾種類型。

非持久型 XSS

非持久型 XSS 漏洞,也叫反射型 XSS 漏洞,一般是通過給別人發送帶有惡意腳本代碼參數的 URL,當 URL 地址被打開時,特有的惡意代碼參數被 HTML 解析、執行。

一個例子,比如你的 Web 頁面中包含有以下代碼:

攻擊者可以直接通過 URL (類似:https://xx.com/xx?default=) 注入可執行的腳本代碼。

非持久型 XSS 漏洞攻擊有以下幾點特徵:

即時性,不經過伺服器存儲,直接通過 HTTP 的 GET 和 POST 請求就能完成一次攻擊,拿到用戶隱私數據。

攻擊者需要誘騙點擊

反饋率低,所以較難發現和響應修復

盜取用戶敏感保密信息

為了防止出現非持久型 XSS 漏洞,需要確保這麼幾件事情:

Web 頁面渲染的所有內容或者渲染的數據都必須來自於服務端。

盡量不要從 URL,, 等這種 DOM API 中獲取數據直接渲染。

盡量不要使用 , ,,,,,, 等可執行字元串的方法。

如果做不到以上幾點,也必須對涉及 DOM 渲染的方法傳入的字元串參數做 escape 轉義。

前端渲染的時候對任何的欄位都需要做 escape 轉義編碼。

escape 轉義的目的是將一些構成 HTML 標籤的元素轉義,比如 ,, 等,轉義成 ,, 等顯示轉義字元。有很多開源的工具可以協助我們做 escape 轉義。


持久型 XSS

持久型 XSS 漏洞,也被稱為存儲型 XSS 漏洞,一般存在於 Form 表單提交等交互功能,如發帖留言,提交文本信息等,黑客利用的 XSS 漏洞,將內容經正常功能提交進入資料庫持久保存,當前端頁面獲得後端從資料庫中讀出的注入代碼時,恰好將其渲染執行。

主要注入頁面方式和非持久型 XSS 漏洞類似,只不過持久型的不是來源於 URL,refferer,forms 等,而是來源於後端從資料庫中讀出來的數據。持久型 XSS 攻擊不需要誘騙點擊,黑客只需要在提交表單的地方完成注入即可,但是這種 XSS 攻擊的成本相對還是很高。攻擊成功需要同時滿足以下幾個條件:

POST 請求提交表單後端沒做轉義直接入庫。

後端從資料庫中取出數據沒做轉義直接輸出給前端。

前端拿到後端數據沒做轉義直接渲染成 DOM。

持久型 XSS 有以下幾個特點:

持久性,植入在資料庫中

危害面廣,甚至可以讓用戶機器變成 DDoS 攻擊的肉雞。

盜取用戶敏感私密信息

為了防止持久型 XSS 漏洞,需要前後端共同努力:

後端在入庫前應該選擇不相信任何前端數據,將所有的欄位統一進行轉義處理。

後端在輸出給前端數據統一進行轉義處理。

前端在渲染頁面 DOM 的時候應該選擇不相信任何後端數據,任何欄位都需要做轉義處理。


基於字符集的 XSS

其實現在很多的瀏覽器以及各種開源的庫都專門針對了 XSS 進行轉義處理,盡量默認抵禦絕大多數 XSS 攻擊,但是還是有很多方式可以繞過轉義規則,讓人防不勝防。比如「基於字符集的 XSS 攻擊」就是繞過這些轉義處理的一種攻擊方式,比如有些 Web 頁面字符集不固定,用戶輸入非期望字符集的字元,有時會繞過轉義過濾規則。

以基於 utf-7 的 XSS 為例

utf-7 是可以將所有的 unicode 通過 7bit 來表示的一種字符集 (但現在已經從 Unicode 規格中移除)。

這個字符集為了通過 7bit 來表示所有的文字, 除去數字和一部分的符號,其它的部分將都以 base64 編碼為基礎的方式呈現。

可以形成「基於字符集的 XSS 攻擊」的原因是由於瀏覽器在 meta 沒有指定 charset 的時候有自動識別編碼的機制,所以這類攻擊通常就是發生在沒有指定或者沒來得及指定 meta 標籤的 charset 的情況下。

所以我們有什麼辦法避免這種 XSS 呢?

記住指定

XML 中不僅要指定字符集為 utf-8,而且標籤要閉合

牛文推薦:http://drops.wooyun.org/papers/1327 (這個講的很詳細)


基於 Flash 的跨站 XSS

基於 Flash 的跨站 XSS 也是屬於反射型 XSS 的一種,雖然現在開發 ActionScript 的產品線幾乎沒有了,但還是提一句吧,AS 腳本可以接受用戶輸入並操作 cookie,攻擊者可以配合其他 XSS(持久型或者非持久型)方法將惡意 swf 文件嵌入頁面中。主要是因為 AS 有時候需要和 JS 傳參交互,攻擊者會通過惡意的 XSS 注入篡改參數,竊取並操作cookie。

避免方法:

嚴格管理 cookie 的讀寫許可權

對 Flash 能接受用戶輸入的參數進行過濾 escape 轉義處理


未經驗證的跳轉 XSS

有一些場景是後端需要對一個傳進來的待跳轉的 URL 參數進行一個 302 跳轉,可能其中會帶有一些用戶的敏感(cookie)信息。如果伺服器端做302 跳轉,跳轉的地址來自用戶的輸入,攻擊者可以輸入一個惡意的跳轉地址來執行腳本。

這時候需要通過以下方式來防止這類漏洞:

對待跳轉的 URL 參數做白名單或者某種規則過濾

後端注意對敏感信息的保護, 比如 cookie 使用來源驗證。


CSRF

CSRF(Cross-Site Request Forgery),中文名稱:跨站請求偽造攻擊

那麼 CSRF 到底能夠幹嘛呢?你可以這樣簡單的理解:攻擊者可以盜用你的登陸信息,以你的身份模擬發送各種請求。攻擊者只要藉助少許的社會工程學的詭計,例如通過 QQ 等聊天軟體發送的鏈接(有些還偽裝成短域名,用戶無法分辨),攻擊者就能迫使 Web 應用的用戶去執行攻擊者預設的操作。例如,當用戶登錄網路銀行去查看其存款餘額,在他沒有退出時,就點擊了一個 QQ 好友發來的鏈接,那麼該用戶銀行帳戶中的資金就有可能被轉移到攻擊者指定的帳戶中。

所以遇到 CSRF 攻擊時,將對終端用戶的數據和操作指令構成嚴重的威脅。當受攻擊的終端用戶具有管理員帳戶的時候,CSRF 攻擊將危及整個 Web 應用程序。


CSRF 原理

下圖大概描述了 CSRF 攻擊的原理,可以理解為有一個小偷在你配鑰匙的地方得到了你家的鑰匙,然後拿著要是去你家想偷什麼偷什麼。

成 CSRF 攻擊必須要有三個條件:

用戶已經登錄了站點 A,並在本地記錄了 cookie

在用戶沒有登出站點 A 的情況下(也就是 cookie 生效的情況下),訪問了惡意攻擊者提供的引誘危險站點 B (B 站點要求訪問站點A)。

站點 A 沒有做任何 CSRF 防禦

你也許會問:「如果我不滿足以上三個條件中的任意一個,就不會受到 CSRF 的攻擊」。其實可以這麼說的,但你不能保證以下情況不會發生:

你不能保證你登錄了一個網站後,不再打開一個 tab 頁面並訪問另外的網站,特別現在瀏覽器都是支持多 tab 的。

你不能保證你關閉瀏覽器了後,你本地的 cookie 立刻過期,你上次的會話已經結束。

上圖中所謂的攻擊網站 B,可能是一個存在其他漏洞的可信任的經常被人訪問的網站。


預防 CSRF

CSRF 的防禦可以從服務端和客戶端兩方面著手,防禦效果是從服務端著手效果比較好,現在一般的 CSRF 防禦也都在服務端進行。服務端的預防 CSRF 攻擊的方式方法有多種,但思路上都是差不多的,主要從以下兩個方面入手:

正確使用 GET,POST 請求和 cookie

在非 GET 請求中增加 token

一般而言,普通的 Web 應用都是以 GET、POST 請求為主,還有一種請求是 cookie 方式。我們一般都是按照如下規則設計應用的請求:

GET 請求常用在查看,列舉,展示等不需要改變資源屬性的時候(資料庫 query 查詢的時候)

POST 請求常用在 From 表單提交,改變一個資源的屬性或者做其他一些事情的時候(資料庫有 insert、update、delete 的時候)

當正確的使用了 GET 和 POST 請求之後,剩下的就是在非 GET 方式的請求中增加隨機數,這個大概有三種方式來進行:

為每個用戶生成一個唯一的 cookie token,所有表單都包含同一個偽隨機值,這種方案最簡單,因為攻擊者不能獲得第三方的 cookie(理論上),所以表單中的數據也就構造失敗,但是由於用戶的 cookie 很容易由於網站的 XSS 漏洞而被盜取,所以這個方案必須要在沒有 XSS 的情況下才安全。

每個 POST 請求使用驗證碼,這個方案算是比較完美的,但是需要用戶多次輸入驗證碼,用戶體驗比較差,所以不適合在業務中大量運用。

渲染表單的時候,為每一個表單包含一個 csrfToken,提交表單的時候,帶上 csrfToken,然後在後端做 csrfToken 驗證。

CSRF 的防禦可以根據應用場景的不同自行選擇。CSRF 的防禦工作確實會在正常業務邏輯的基礎上帶來很多額外的開發量,但是這種工作量是值得的,畢竟用戶隱私以及財產安全是產品最基礎的根本。

SQL 注入

SQL 注入漏洞(SQL Injection)是 Web 開發中最常見的一種安全漏洞。可以用它來從資料庫獲取敏感信息,或者利用資料庫的特性執行添加用戶,導出文件等一系列惡意操作,甚至有可能獲取資料庫乃至系統用戶最高許可權。

而造成 SQL 注入的原因是因為程序沒有有效的轉義過濾用戶的輸入,使攻擊者成功的向伺服器提交惡意的 SQL 查詢代碼,程序在接收後錯誤的將攻擊者的輸入作為查詢語句的一部分執行,導致原始的查詢邏輯被改變,額外的執行了攻擊者精心構造的惡意代碼。

很多 Web 開發者沒有意識到 SQL 查詢是可以被篡改的,從而把 SQL 查詢當作可信任的命令。殊不知,SQL 查詢是可以繞開訪問控制,從而繞過身份驗證和許可權檢查的。更有甚者,有可能通過 SQL 查詢去運行主機系統級的命令。

本文內容限於篇幅過長,未能完全引用,

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 PHP技術大全 的精彩文章:

馬云:我不懂技術但欣賞技術 達摩院必須超越微軟

TAG:PHP技術大全 |