前端網絡安全

有哪些可能引起前端安全的的問題

  • 跨站腳本 (Cross-Site Scripting, XSS): 一種代碼注入方式, 爲了與 CSS 區分所以被稱作 XSS. 早期常見於網絡論壇, 起因是網站沒有對用戶的輸入進行嚴格的限制, 使得攻擊者可以將腳本上傳到帖子讓其他人瀏覽到有惡意腳本的頁面, 其注入方式很簡單包括但不限於 JavaScript / VBScript / CSS / Flash 等
  • iframe的濫用: iframe中的內容是由第三方來提供的,默認情況下他們不受我們的控制,他們可以在iframe中運行JavaScirpt腳本、Flash插件、彈出對話框等等,這可能會破壞前端用戶體驗
  • 跨站點請求僞造(Cross-Site Request Forgeries,CSRF): 指攻擊者通過設置好的陷阱,強制對已完成認證的用戶進行非預期的個人信息或設定信息等某些狀態更新,屬於被動攻擊
  • 惡意第三方庫: 無論是後端服務器應用還是前端應用開發,絕大多數時候我們都是在藉助開發框架和各種類庫進行快速開發,一旦第三方庫被植入惡意代碼很容易引起安全問題,比如event-stream的惡意代碼事件,2018年11月21日,名爲 FallingSnow的用戶在知名JavaScript應用庫event-stream在github Issuse中發佈了針對植入的惡意代碼的疑問,表示event-stream中存在用於竊取用戶數字錢包的惡意代碼

XSS分類

根據攻擊的來源,XSS 攻擊可分爲存儲型、反射型和 DOM 型三種。

存儲型 XSS

存儲型 XSS 的攻擊步驟:

  1. 攻擊者將惡意代碼提交到目標網站的數據庫中。
  2. 用戶打開目標網站時,網站服務端將惡意代碼從數據庫取出,拼接在 HTML 中返回給瀏覽器。
  3. 用戶瀏覽器接收到響應後解析執行,混在其中的惡意代碼也被執行。
  4. 惡意代碼竊取用戶數據併發送到攻擊者的網站,或者冒充用戶的行爲,調用目標網站接口執行攻擊者指定的操作。

這種攻擊常見於帶有用戶保存數據的網站功能,如論壇發帖、商品評論、用戶私信等。

反射型 XSS

反射型 XSS 的攻擊步驟:

  1. 攻擊者構造出特殊的 URL,其中包含惡意代碼。
  2. 用戶打開帶有惡意代碼的 URL 時,網站服務端將惡意代碼從 URL 中取出,拼接在 HTML 中返回給瀏覽器。、
  3. 用戶瀏覽器接收到響應後解析執行,混在其中的惡意代碼也被執行。
  4. 惡意代碼竊取用戶數據併發送到攻擊者的網站,或者冒充用戶的行爲,調用目標網站接口執行攻擊者指定的操作。

反射型 XSS 跟存儲型 XSS 的區別是:存儲型 XSS 的惡意代碼存在數據庫裏,反射型 XSS 的惡意代碼存在 URL 裏。

反射型 XSS 漏洞常見於通過 URL 傳遞參數的功能,如網站搜索、跳轉等。

由於需要用戶主動打開惡意的 URL 才能生效,攻擊者往往會結合多種手段誘導用戶點擊。
POST 的內容也可以觸發反射型 XSS,只不過其觸發條件比較苛刻(需要構造表單提交頁面,並引導用戶點擊),所以非常少見

DOM 型 XSS

DOM 型 XSS 的攻擊步驟:

  1. 攻擊者構造出特殊的 URL,其中包含惡意代碼。
  2. 用戶打開帶有惡意代碼的 URL。
  3. 用戶瀏覽器接收到響應後解析執行,前端 JavaScript 取出 URL 中的惡意代碼並執行。
  4. 惡意代碼竊取用戶數據併發送到攻擊者的網站,或者冒充用戶的行爲,調用目標網站接口執行攻擊者指定的操作。

DOM 型 XSS 跟前兩種 XSS 的區別:DOM 型 XSS 攻擊中,取出和執行惡意代碼由瀏覽器端完成,屬於前端 JavaScript 自身的安全漏洞,而其他兩種 XSS 都屬於服務端的安全漏洞

危害:

  1. 盜用 cookie ,獲取敏感信息
  2. 利用植入 Flash ,通過 crossdomain 權限設置進一步獲取更高權限;或者利用Java等得到類似的操作
  3. 利用 iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻擊)用戶的身份執行一些管理動作,或執行一些一般的如發微博、加好友、發私信等操作
  4. 利用可被攻擊的域受到其他域信任的特點,以受信任來源的身份請求一些平時不允許的操作,如進行不當的投票活動
  5. 在訪問量極大的一些頁面上的XSS可以攻擊一些小型網站,實現DDoS攻擊的效果

如何預防XSS

XSS 攻擊有兩大要素:

  1. 攻擊者提交惡意代碼。
  2. 瀏覽器執行惡意代碼。

輸入過濾

輸入側過濾能夠在某些情況下解決特定的 XSS 問題,但會引入很大的不確定性和亂碼問題。

當然,對於明確的輸入類型,例如數字、URL、電話號碼、郵件地址等等內容,進行輸入過濾還是必要的。

預防存儲型和反射型 XSS 攻擊

存儲型和反射型 XSS 都是在服務端取出惡意代碼後,插入到響應 HTML 裏的,攻擊者刻意編寫的“數據”被內嵌到“代碼”中,被瀏覽器所執行。

預防這兩種漏洞,有兩種常見做法:

  1. 改成純前端渲染,把代碼和數據分隔開。
  2. 對 HTML 做充分轉義

預防 DOM 型 XSS 攻擊

DOM 型 XSS 攻擊,實際上就是網站前端 JavaScript 代碼本身不夠嚴謹,把不可信的數據當作代碼執行了。

在使用 .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,很容易產生安全隱患,請務必避免。

<!-- 內聯事件監聽器中包含惡意代碼 -->
![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2018b/3e724ce0.data:image/png,)
<!-- 鏈接內包含惡意代碼 -->
<a href="UNTRUSTED">1</a>
<script>
// setTimeout()/setInterval() 中調用惡意代碼
setTimeout("UNTRUSTED")
setInterval("UNTRUSTED")
// location 調用惡意代碼
location.href = 'UNTRUSTED'
// eval() 中調用惡意代碼
eval("UNTRUSTED")
</script>

其他 XSS 防範措施

  1. 嚴格的 CSP(Content Security Policy)
  2. 輸入內容長度控制
  3. HTTP-only Cookie: 禁止 JavaScript 讀取某些敏感 Cookie,攻擊者完成 XSS 注入後也無法竊取此 Cookie。
  4. 驗證碼:防止腳本冒充用戶提交危險操作。

CSRF

CSRF(Cross-site request forgery)跨站請求僞造:攻擊者誘導受害者進入第三方網站,在第三方網站中,向被攻擊網站發送跨站請求。利用受害者在被攻擊網站已經獲取的註冊憑證,繞過後臺的用戶驗證,達到冒充用戶對被攻擊的網站執行某項操作的目的。

CSRF攻擊流程

  1. 受害者登錄 a.com,並保留了登錄憑證(Cookie)
  2. 攻擊者引誘受害者訪問了b.com
  3. b.com 向 a.com 發送了一個請求:a.com/act=xx瀏覽器會默認攜帶a.com的Cookie
  4. a.com接收到請求後,對請求進行驗證,並確認是受害者的憑證,誤以爲是受害者自己發送的請求
  5. a.com以受害者的名義執行了act=xx
  6. 攻擊完成,攻擊者在受害者不知情的情況下,冒充受害者,讓a.com執行了自己定義的操作
    在這裏插入圖片描述

CSRF的攻擊類型

GET類型的CSRF

GET類型的CSRF利用非常簡單,只需要一個HTTP請求,一般會這樣利用:

https://awps-assets.meituan.net/mit-x/blog-images-bundle-2018b/ff0cdbee.example/withdraw?amount=10000&for=hacker

受害者訪問含有這個img的頁面後,瀏覽器會自動向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker發出一次HTTP請求。bank.example就會收到包含受害者登錄信息的一次跨域請求。

POST類型的CSRF

這種類型的CSRF利用起來通常使用的是一個自動提交的表單,如:

<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操作。

POST類型的攻擊通常比GET要求更加嚴格一點,但仍並不複雜。任何個人網站、博客,被黑客上傳頁面的網站都有可能是發起攻擊的來源,後端接口不能將安全寄託在僅允許POST上面。

鏈接類型的CSRF

鏈接類型的CSRF並不常見,比起其他兩種用戶打開頁面就中招的情況,這種需要用戶點擊鏈接纔會觸發。這種類型通常是在論壇中發佈的圖片中嵌入惡意鏈接,或者以廣告的形式誘導用戶中招,攻擊者通常會以比較誇張的詞語誘騙用戶點擊,例如:

<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
  重磅消息!!
<a/>

由於之前用戶登錄了信任的網站A,並且保存登錄狀態,只要用戶主動訪問上面的這個PHP頁面,則表示攻擊成功.

如何預防CSRF

CSRF通常從第三方網站發起,被攻擊的網站無法防止攻擊發生,只能通過增強自己網站針對CSRF的防護能力來提升安全性。

CSRF的兩個特點:

  1. CSRF(通常)發生在第三方域名。
  2. CSRF攻擊者不能獲取到Cookie等信息,只是使用。

針對這兩點,我們可以專門制定防護策略,如下:

  • 阻止不明外域的訪問
    • 同源檢測
    • Samesite Cookie
  • 提交時要求附加本域才能獲取的信息
    • CSRF Token
    • 雙重Cookie驗證

同源檢測

既然CSRF大多來自第三方網站,那麼我們就直接禁止外域(或者不受信任的域名)對我們發起請求:

  • 使用Origin Header確定來源域名: 在部分與CSRF有關的請求中,請求的Header中會攜帶Origin字段,如果Origin存在,那麼直接使用Origin中的字段確認來源域名就可以
  • 使用Referer Header確定來源域名: 根據HTTP協議,在HTTP頭中有一個字段叫Referer,記錄了該HTTP請求的來源地址

CSRF Token

CSRF的另一個特徵是,攻擊者無法直接竊取到用戶的信息(Cookie,Header,網站內容等),僅僅是冒用Cookie中的信息。

而CSRF攻擊之所以能夠成功,是因爲服務器誤把攻擊者發送的請求當成了用戶自己的請求。那麼我們可以要求所有的用戶請求都攜帶一個CSRF攻擊者無法獲取到的Token。服務器通過校驗請求是否攜帶正確的Token,來把正常的請求和攻擊的請求區分開,也可以防範CSRF的攻擊:

CSRF Token的防護策略分爲三個步驟:

  1. 將CSRF Token輸出到頁面中
  2. 頁面提交的請求攜帶這個Token
  3. 服務器驗證Token是否正確

雙重Cookie驗證

在會話中存儲CSRF Token比較繁瑣,而且不能在通用的攔截上統一處理所有的接口

那麼另一種防禦措施是使用雙重提交Cookie。利用CSRF攻擊不能獲取到用戶Cookie的特點,我們可以要求Ajax和表單請求攜帶一個Cookie中的值

雙重Cookie採用以下流程:

  • 在用戶訪問網站頁面時,向請求域名注入一個Cookie,內容爲隨機字符串(例如csrfcookie=v8g9e4ksfhw)。
  • 在前端向後端發起請求時,取出Cookie,並添加到URL的參數中(接上例POST https://www.a.com/comment?csrfcookie=v8g9e4ksfhw)。
  • 後端接口驗證Cookie中的字段與URL參數中的字段是否一致,不一致則拒絕

Samesite Cookie屬性

Google起草了一份草案來改進HTTP協議,那就是爲Set-Cookie響應頭新增Samesite屬性,它用來標明這個 Cookie是個“同站 Cookie”,同站Cookie只能作爲第一方Cookie,不能作爲第三方Cookie,Samesite 有兩個屬性值:

  • Samesite=Strict: 這種稱爲嚴格模式,表明這個 Cookie 在任何情況下都不可能作爲第三方 Cookie
  • Samesite=Lax: 這種稱爲寬鬆模式,比 Strict 放寬了點限制,假如這個請求是這種請求且同時是個GET請求,則這個Cookie可以作爲第三方Cookie

網絡劫持有哪幾種

網絡劫持一般分爲兩種:

  • DNS劫持: (輸入京東被強制跳轉到淘寶這就屬於dns劫持)

    • DNS強制解析: 通過修改運營商的本地DNS記錄,來引導用戶流量到緩存服務器
    • 302跳轉的方式: 通過監控網絡出口的流量,分析判斷哪些內容是可以進行劫持處理的,再對劫持的內存發起302跳轉的回覆,引導用戶獲取內容
  • HTTP劫持: (訪問谷歌但是一直有貪玩藍月的廣告),由於http明文傳輸,運營商會修改你的http響應內容(即加廣告)

中間人攻擊

中間人 (Man-in-the-middle attack, MITM) 是指攻擊者與通訊的兩端分別創建獨立的聯繫, 並交換其所收到的數據, 使通訊的兩端認爲他們正在通過一個私密的連接與對方直接對話, 但事實上整個會話都被攻擊者完全控制. 在中間人攻擊中, 攻擊者可以攔截通訊雙方的通話並插入新的內容.

一般的過程如下:

  1. 客戶端發送請求到服務端,請求被中間人截獲
  2. 服務器向客戶端發送公鑰
  3. 中間人截獲公鑰,保留在自己手上。然後自己生成一個【僞造的】公鑰,發給客戶端
  4. 客戶端收到僞造的公鑰後,生成加密hash值發給服務器
  5. 中間人獲得加密hash值,用自己的私鑰解密獲得真祕鑰,同時生成假的加密hash值,發給服務器
  6. 服務器用私鑰解密獲得假密鑰,然後加密數據傳輸給客戶端
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章