一、是什麼 Web攻擊(WebAttack)是針對用戶上網行為或網站伺服器等設備進行攻擊的行為 如植入惡意代碼,修改網站許可權,獲取網站用戶隱私信息等等 Web應用程式的安全性是任何基於Web業務的重要組成部分 確保Web應用程式安全十分重要,即使是代碼中很小的 bug 也有可能導致隱私信息被泄露 站 ...
一、是什麼
Web攻擊(WebAttack)是針對用戶上網行為或網站伺服器等設備進行攻擊的行為
如植入惡意代碼,修改網站許可權,獲取網站用戶隱私信息等等
Web應用程式的安全性是任何基於Web業務的重要組成部分
確保Web應用程式安全十分重要,即使是代碼中很小的 bug 也有可能導致隱私信息被泄露
站點安全就是為保護站點不受未授權的訪問、使用、修改和破壞而採取的行為或實踐
我們常見的Web攻擊方式有
- XSS (Cross Site Scripting) 跨站腳本攻擊
- CSRF(Cross-site request forgery)跨站請求偽造
- SQL註入攻擊
二、XSS
XSS,跨站腳本攻擊,允許攻擊者將惡意代碼植入到提供給其它用戶使用的頁面中
XSS
涉及到三方,即攻擊者、客戶端與Web
應用
XSS
的攻擊目標是為了盜取存儲在客戶端的cookie
或者其他網站用於識別客戶端身份的敏感信息。一旦獲取到合法用戶的信息後,攻擊者甚至可以假冒合法用戶與網站進行交互
舉個例子:
一個搜索頁面,根據url
參數決定關鍵詞的內容
<input type="text" value="<%= getParameter("keyword") %>"> <button>搜索</button> <div> 您搜索的關鍵詞是:<%= getParameter("keyword") %> </div>
這裡看似並沒有問題,但是如果不按套路出牌呢?
用戶輸入"><script>alert('XSS');</script>
,拼接到 HTML 中返回給瀏覽器。形成瞭如下的 HTML:
<input type="text" value=""><script>alert('XSS');</script>"> <button>搜索</button> <div> 您搜索的關鍵詞是:"><script>alert('XSS');</script> </div>
瀏覽器無法分辨出 <script>alert('XSS');</script>
是惡意代碼,因而將其執行,試想一下,如果是獲取cookie
發送對黑客伺服器呢?
根據攻擊的來源,XSS
攻擊可以分成:
- 存儲型
- 反射型
- DOM 型
#存儲型
存儲型 XSS 的攻擊步驟:
- 攻擊者將惡意代碼提交到目標網站的資料庫中
- 用戶打開目標網站時,網站服務端將惡意代碼從資料庫取出,拼接在 HTML 中返回給瀏覽器
- 用戶瀏覽器接收到響應後解析執行,混在其中的惡意代碼也被執行
- 惡意代碼竊取用戶數據併發送到攻擊者的網站,或者冒充用戶的行為,調用目標網站介面執行攻擊者指定的操作
這種攻擊常見於帶有用戶保存數據的網站功能,如論壇發帖、商品評論、用戶私信等
#反射型 XSS
反射型 XSS 的攻擊步驟:
- 攻擊者構造出特殊的 URL,其中包含惡意代碼
- 用戶打開帶有惡意代碼的 URL 時,網站服務端將惡意代碼從 URL 中取出,拼接在 HTML 中返回給瀏覽器
- 用戶瀏覽器接收到響應後解析執行,混在其中的惡意代碼也被執行
- 惡意代碼竊取用戶數據併發送到攻擊者的網站,或者冒充用戶的行為,調用目標網站介面執行攻擊者指定的操作
反射型 XSS 跟存儲型 XSS 的區別是:存儲型 XSS 的惡意代碼存在資料庫里,反射型 XSS 的惡意代碼存在 URL 里。
反射型 XSS 漏洞常見於通過 URL 傳遞參數的功能,如網站搜索、跳轉等。
由於需要用戶主動打開惡意的 URL 才能生效,攻擊者往往會結合多種手段誘導用戶點擊。
POST 的內容也可以觸發反射型 XSS,只不過其觸發條件比較苛刻(需要構造表單提交頁面,並引導用戶點擊),所以非常少見
DOM 型 XSS
DOM 型 XSS 的攻擊步驟:
- 攻擊者構造出特殊的 URL,其中包含惡意代碼
- 用戶打開帶有惡意代碼的 URL
- 用戶瀏覽器接收到響應後解析執行,前端 JavaScript 取出 URL 中的惡意代碼並執行
- 惡意代碼竊取用戶數據併發送到攻擊者的網站,或者冒充用戶的行為,調用目標網站介面執行攻擊者指定的操作
DOM 型 XSS 跟前兩種 XSS 的區別:DOM 型 XSS 攻擊中,取出和執行惡意代碼由瀏覽器端完成,屬於前端 JavaScript 自身的安全漏洞,而其他兩種 XSS 都屬於服務端的安全漏洞
XSS的預防
通過前面介紹,看到XSS
攻擊的兩大要素:
- 攻擊者提交而惡意代碼
- 瀏覽器執行惡意代碼
針對第一個要素,我們在用戶輸入的過程中,過濾掉用戶輸入的惡劣代碼,然後提交給後端,但是如果攻擊者繞開前端請求,直接構造請求就不能預防了
而如果在後端寫入資料庫前,對輸入進行過濾,然後把內容給前端,但是這個內容在不同地方就會有不同顯示
例如:
一個正常的用戶輸入了 5 < 7
這個內容,在寫入資料庫前,被轉義,變成了 5 < 7
在客戶端中,一旦經過了 escapeHTML()
,客戶端顯示的內容就變成了亂碼( 5 < 7
)
在前端中,不同的位置所需的編碼也不同。
- 當
5 < 7
作為 HTML 拼接頁面時,可以正常顯示:
<div title="comment">5 < 7</div>
- 當
5 < 7
通過 Ajax 返回,然後賦值給 JavaScript 的變數時,前端得到的字元串就是轉義後的字元。這個內容不能直接用於 Vue 等模板的展示,也不能直接用於內容長度計算。不能用於標題、alert 等
可以看到,過濾並非可靠的,下麵就要通過防止瀏覽器執行惡意代碼:
在使用 .innerHTML
、.outerHTML
、document.write()
時要特別小心,不要把不可信的數據作為 HTML 插到頁面上,而應儘量使用 .textContent
、.setAttribute()
等
如果用 Vue/React
技術棧,並且不使用 v-html
/dangerouslySetInnerHTML
功能,就在前端 render
階段避免 innerHTML
、outerHTML
的 XSS 隱患
DOM 中的內聯事件監聽器,如 location
、onclick
、onerror
、onload
、onmouseover
等,<a>
標簽的 href
屬性,JavaScript 的 eval()
、setTimeout()
、setInterval()
等,都能把字元串作為代碼運行。如果不可信的數據拼接到字元串中傳遞給這些 API,很容易產生安全隱患,請務必避免
<!-- 鏈接內包含惡意代碼 --> < a href=" ">1</ a> <script> // setTimeout()/setInterval() 中調用惡意代碼 setTimeout("UNTRUSTED") setInterval("UNTRUSTED") // location 調用惡意代碼 location.href = 'UNTRUSTED' // eval() 中調用惡意代碼 eval("UNTRUSTED")
三、CSRF
CSRF(Cross-site request forgery)跨站請求偽造:攻擊者誘導受害者進入第三方網站,在第三方網站中,向被攻擊網站發送跨站請求
利用受害者在被攻擊網站已經獲取的註冊憑證,繞過後臺的用戶驗證,達到冒充用戶對被攻擊的網站執行某項操作的目
一個典型的CSRF攻擊有著如下的流程:
- 受害者登錄a.com,並保留了登錄憑證(Cookie)
- 攻擊者引誘受害者訪問了b.com
- b.com 向 a.com 發送了一個請求:a.com/act=xx。瀏覽器會預設攜帶a.com的Cookie
- a.com接收到請求後,對請求進行驗證,並確認是受害者的憑證,誤以為是受害者自己發送的請求
- a.com以受害者的名義執行了act=xx
- 攻擊完成,攻擊者在受害者不知情的情況下,冒充受害者,讓a.com執行了自己定義的操作
csrf
可以通過get
請求,即通過訪問img
的頁面後,瀏覽器自動訪問目標地址,發送請求
同樣,也可以設置一個自動提交的表單發送post
請求,如下:
<form action="http://bank.example/withdraw" method=POST> <input type="hidden" name="account" value="xiaoming" /> <input type="hidden" name="amount" value="10000" /> <input type="hidden" name="for" value="hacker" /> </form> <script> document.forms[0].submit(); </script>
訪問該頁面後,表單會自動提交,相當於模擬用戶完成了一次POST
操作
還有一種為使用a
標簽的,需要用戶點擊鏈接才會觸發
訪問該頁面後,表單會自動提交,相當於模擬用戶完成了一次POST操作
< a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank"> 重磅消息!! <a/>
CSRF的特點
- 攻擊一般發起在第三方網站,而不是被攻擊的網站。被攻擊的網站無法防止攻擊發生
- 攻擊利用受害者在被攻擊網站的登錄憑證,冒充受害者提交操作;而不是直接竊取數據
- 整個過程攻擊者並不能獲取到受害者的登錄憑證,僅僅是“冒用”
- 跨站請求可以用各種方式:圖片URL、超鏈接、CORS、Form提交等等。部分請求方式可以直接嵌入在第三方論壇、文章中,難以進行追蹤
CSRF的預防
CSRF通常從第三方網站發起,被攻擊的網站無法防止攻擊發生,只能通過增強自己網站針對CSRF的防護能力來提升安全性
防止csrf
常用方案如下:
- 阻止不明外域的訪問
- 同源檢測
- Samesite Cookie
- 提交時要求附加本域才能獲取的信息
- CSRF Token
- 雙重Cookie驗證
這裡主要講講token
這種形式,流程如下:
- 用戶打開頁面的時候,伺服器需要給這個用戶生成一個Token
- 對於GET請求,Token將附在請求地址之後。對於 POST 請求來說,要在 form 的最後加上
<input type=”hidden” name=”csrftoken” value=”tokenvalue”/>
- 當用戶從客戶端得到了Token,再次提交給伺服器的時候,伺服器需要判斷Token的有效性
四、SQL註入
Sql 註入攻擊,是通過將惡意的 Sql
查詢或添加語句插入到應用的輸入參數中,再在後臺 Sql
伺服器上解析執行進行的攻擊
流程如下所示:
-
找出SQL漏洞的註入點
-
判斷資料庫的類型以及版本
-
猜解用戶名和密碼
-
利用工具查找Web後臺管理入口
-
入侵和破壞
預防方式如下:
- 嚴格檢查輸入變數的類型和格式
- 過濾和轉義特殊字元
- 對訪問資料庫的Web應用程式採用Web應用防火牆
上述只是列舉了常見的web
攻擊方式,實際開發過程中還會遇到很多安全問題,對於這些問題, 切記不可忽視
參考文獻
- https://tech.meituan.com/2018/09/27/fe-security.html
- https://developer.mozilla.org/zh-CN/docs/learn/Server-side/First_steps/Website_security
如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。