瀏覽器視角下的Web安全
前言
之前筆者所學習的有關web安全的知識,都是以前端的角度來看,所以跟前端最相關、最有印象的就是利用input
作XSS攻擊,而其他的話就沒有什麼涉略了。然而,最近開始學習瀏覽器相關的知識之後,了解如果以瀏覽器的角度來看待Web安全的議題,其實會更全面一些。
以瀏覽器的角度來看待Web安全,可以大致分為Web頁面安全、瀏覽器網路安全、瀏覽器系統安全等。
Web頁面安全
同源策略(Same-origin policy)
如果兩個URL的協議、域名和端口都一樣,就可以稱這兩個URL同源;而同源策略(Same-origin policy),就是要保證在一個頁面中,只能使用、請求來自同源的資源。
如果沒有同源策略,那麼會發生什麼事呢?假如我們打開一個銀行頁面、然後又不小心點開了一個惡意站點,那惡意站點就可以隨意修改銀行頁面上面的dom、甚至監聽我們在銀行頁面上的行為。因此,同源策略算是在網路中最基本的安全保障,起碼不是像在網路上裸奔一樣、什麼行為都可以被觀測到。
而同源策略,可以體現在DOM、web數據和網路等3個層面
DOM層面
- 如果是有同源關係的兩個頁面,可以用Javascript來跨頁面操作DOM節點;但如果不是同源,就會被限制。
如進入 XXX 網站,點開分頁,然後在console中輸入:
{ let pdom = opener.document pdom.body.style.display = "none" }
該dom就會被取消
數據層面
- 同源策略限制不同源的站點讀取當前站點的Cookie、IndexDB、LocalStorage等數據。
- 基於同源策略,沒辦法透過第二個頁面的opener來讀取
網路層面
- 同源策略限制了通過 XMLHttpRequest 等方式把站點的數據發送給不同源的站點
然而,如果完全限制一個頁面只能使用同源的資源,雖然保證了安全、但也十分不便利。因此同源策略是有以下的讓步:
- 頁面中可以嵌入第三方資源
- 代表頁面可以使用CDN來引入資源,但需要配置CSP來防止XSS攻擊
- 跨域資源共享和跨文檔消息機制
- XMLHttpRequest 和 Fetch 是無法直接進行非同源資源的請求,因此瀏覽器引入 CORS(跨域資源共享),讓其可以安全的進行跨域請求
- 兩個不同源的DOM是無法互相操作,因此瀏覽器引跨文檔消息機制,可以透過
window.postMessag
的JS接口來和不同源的DOM進行通信。
XSS攻擊(Cross Site Scripting)
XSS攻擊,主要就是利用各種方式、在頁面中共注入惡意Javascript腳本,然後就可以進行Hacker想要做的事情,例如竊取Cookie資料、修改DOM、監聽用戶行為、廣告dialog等等。而要如何注入惡意腳本?主要有三個類型:
- 存儲型XSS攻擊
- hecker利用網頁漏洞,把惡意腳本上傳到要攻擊的服務器。最典型的就是利用頁面中的
input
來將腳本上傳到該服務器。 - 而當用戶向網站請求的包含惡意腳本的頁面後,惡意腳本也會被跟著被請求、進而執行。
- hecker利用網頁漏洞,把惡意腳本上傳到要攻擊的服務器。最典型的就是利用頁面中的
反射型XSS攻擊
- 常見的是用戶不小心點擊了駭客的連結
該連結將一段含有惡意代碼的請求提交給了Web服務器,Web服務器接收到請求後,又將惡意代碼反射給了瀏覽器端。以NodeJS做個簡單的demo:
var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: 'Express',xss:req.query.xss }); }); module.exports = router;
如果用戶點擊的URL為
http://www.xxx.com?xss=<script>alert('attack!!')</script>
,就是被XSS攻擊的簡單示意
基於DOM的XSS 攻擊
- 不會牽扯到服務器,可能透過WIFI或本地的惡意軟體
- 利用網路劫持,在頁面傳輸的過程中修改HTML頁面的內容、數據。
那麼,要如何防範XSS攻擊呢?
- 通過服務器對輸入的內容進行過濾,不要讓script入庫
- 充分利用好CSP
- Cookie設置
HttpOnly
,因為 Javascript 無法讀取在 Cookie中設置了HttpOnly
的數據
CSRF攻擊(Cross-site request forgery)
CSRF攻擊、又名跨站請求偽造,主要是建立在有CSRF漏洞的網站,那些網站會在用戶的瀏覽器中紀錄登入資訊,雖然其用意是讓用戶方便、不用重新登入;但這也給了駭客趁虛而入的機會,利用用戶的登入狀態,在第三方站點進行惡意操作。
這邊以Facebook為例,假設用戶在Facebook登入後,Facebook會在瀏覽器cookie中簡單紀錄用戶的登入狀態;同時,Facebook也支持轉帳功能,API如下:
# 同時支持 GET、POST
# 接口
https://www.facebook.com/sendcoin
# 參數
## 目標用戶
user
## 金額
number
# 範例:向user Davie 轉帳1000元
https://www.facebook.com/sendcoin?user=Davie&number=1000
這個時候,駭客就可以有幾種簡單的攻擊手法:
自動發起Get請求,例如:把請求網址藏到
img
裡面<!DOCTYPE html> <html> <body> <h1>Hecker CSRF Attack Example</h1> <img src="https://www.facebook.com/sendcoin?user=hacker&number=1000"> </body> </html>
- 如此一來,用戶一旦進入該頁面、而且本身瀏覽器有用戶登入Cookie,便會自動發起轉帳
自動發起POST
<!DOCTYPE html> <html> <body> <h1>Hecker CSRF Attack Example</h1> <form id='hacker-form' action="https://www.facebook.com/sendcoin" method=POST> <input type="hidden" name="user" value="hacker" /> <input type="hidden" name="number" value="100" /> </form> <script> document.getElementById('hacker-form').submit(); </script> </body> </html>
- 可以看到,黑客在頁面中建立一個隱藏的Form,然後用戶進入頁面後,會自動發起這個Form的submit
引誘用戶點擊,也是用同樣的原理。
那麼要如何防止CSRF攻擊?
- 充分利用好 Cookie 的 SameSite 属性
- 在 HTTP header中,通過set-cookie 字段設置 Cookie 時,可可以帶上
SameSite
選項來禁止第三方使用。SameSite
選項通常有Strict、Lax 和 None。
- Strict 為完全禁止第三方的使用
- Lax 為允許部分 HTML 標籤情況下發送第三方 Cookie
- 在 HTTP header中,通過set-cookie 字段設置 Cookie 時,可可以帶上
- server端要驗證請求的來源站點
瀏覽器系統安全
這個部分簡單來說,就是瀏覽器利用 Browser Sandboxing
,將 Render Process和其他Process給隔離開。
就像是,我們下載了一個惡意軟體,但我們沒有去執行它,那麼它就不會對我們的電腦造成傷害。那麼,當瀏覽器下載的頁面包含了對操作系統有害的腳本,然後Render Process 執行了該腳本,如果沒有對 Render Process 進行隔離,那麼該腳本就真的可以觸碰到操作系統、並進行惡意腳本;引進了Browser Sandboxing
,就可以對Render Process和操作系統進行隔離,這樣就算Render Process因為漏洞而被攻擊,也不會影響到本地電腦的操作系統。
瀏覽器網路安全
HTTPS
瀏覽器中的網路安全,防止中間人攻擊
- 數字證書(Digital Certificate)
- 利用數字證書向瀏覽器證明服務器的身分
- 數字證書裡包含了服務器的公鑰
ChangeLog
- 20221102 - 初稿
Ref
- 極客時間:《瀏覽器原理與實踐》