[Frontend筆記]瀏覽器視角下的Web安全

極簡前端安全筆記

Posted by 李定宇 on Wednesday, November 2, 2022

瀏覽器視角下的Web安全

前言

之前筆者所學習的有關web安全的知識,都是以前端的角度來看,所以跟前端最相關、最有印象的就是利用input作XSS攻擊,而其他的話就沒有什麼涉略了。然而,最近開始學習瀏覽器相關的知識之後,了解如果以瀏覽器的角度來看待Web安全的議題,其實會更全面一些。

以瀏覽器的角度來看待Web安全,可以大致分為Web頁面安全、瀏覽器網路安全、瀏覽器系統安全等。

Web頁面安全

同源策略(Same-origin policy)

如果兩個URL的協議、域名和端口都一樣,就可以稱這兩個URL同源;而同源策略(Same-origin policy),就是要保證在一個頁面中,只能使用、請求來自同源的資源。

如果沒有同源策略,那麼會發生什麼事呢?假如我們打開一個銀行頁面、然後又不小心點開了一個惡意站點,那惡意站點就可以隨意修改銀行頁面上面的dom、甚至監聽我們在銀行頁面上的行為。因此,同源策略算是在網路中最基本的安全保障,起碼不是像在網路上裸奔一樣、什麼行為都可以被觀測到。

而同源策略,可以體現在DOMweb數據網路等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來將腳本上傳到該服務器。
    • 而當用戶向網站請求的包含惡意腳本的頁面後,惡意腳本也會被跟著被請求、進而執行。
  • 反射型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
  • server端要驗證請求的來源站點

瀏覽器系統安全

這個部分簡單來說,就是瀏覽器利用 Browser Sandboxing,將 Render Process和其他Process給隔離開。

就像是,我們下載了一個惡意軟體,但我們沒有去執行它,那麼它就不會對我們的電腦造成傷害。那麼,當瀏覽器下載的頁面包含了對操作系統有害的腳本,然後Render Process 執行了該腳本,如果沒有對 Render Process 進行隔離,那麼該腳本就真的可以觸碰到操作系統、並進行惡意腳本;引進了Browser Sandboxing,就可以對Render Process和操作系統進行隔離,這樣就算Render Process因為漏洞而被攻擊,也不會影響到本地電腦的操作系統。

瀏覽器網路安全

HTTPS

瀏覽器中的網路安全,防止中間人攻擊

ChangeLog

  • 20221102 - 初稿

Ref