使用擷取中繼資料功能,保護資源不受網路攻擊

防止 CSRF、XSSI 和跨來源資訊外洩。

Lukas Weichselbaum
Lukas Weichselbaum

為何您應該重視區隔網路資源?

許多網頁應用程式容易遭受跨來源攻擊,例如跨網站要求偽造 (CSRF)、跨網站指令碼納入 (XSSI)、時間攻擊、跨來源資訊外洩或推測執行端 (Spectre) 攻擊。

擷取中繼資料要求標頭可讓您部署強大的深度防禦機制,即「資源隔離政策」,協助應用程式防範這些常見的跨來源攻擊。

特定網頁應用程式公開的資源通常只由應用程式本身載入,而不由其他網站載入。在這類情況下,根據擷取中繼資料要求標頭部署資源隔離政策不需花費太多心力,同時也能防止應用程式遭受跨網站攻擊。

瀏覽器相容性

所有新型瀏覽器引擎都支援擷取中繼資料要求標頭。

瀏覽器支援

  • 76
  • 79
  • 90
  • 16.4

資料來源

背景

由於網路預設為開啟,應用程式伺服器無法輕易防止本身受到外部應用程式的通訊影響,因此可能會受到許多跨網站攻擊。典型的跨來源攻擊是指跨網站要求偽造 (CSRF),攻擊者會在他們控制的網站中,將使用者提交表單給使用者登入的伺服器。由於伺服器無法分辨要求是否來自另一個網域 (跨網站),且瀏覽器會自動將 Cookie 附加至跨網站要求,因此伺服器會代表使用者執行攻擊者所要求的動作。

其他跨網站攻擊如跨網站指令碼納入 (XSSI) 或跨來源資訊洩露與 CSRF 的本質類似,依賴受害者應用程式載入受害者應用程式的內容,並洩露受害者應用程式的相關資訊。由於應用程式無法輕易區別可信任要求和不受信任的要求,因此無法捨棄惡意的跨網站流量。

擷取中繼資料簡介

擷取中繼資料要求標頭是新的網路平台安全性功能,旨在協助伺服器防禦跨來源攻擊。透過在一組 Sec-Fetch-* 標頭中提供 HTTP 要求內容的相關資訊,可讓回應伺服器在處理要求之前套用安全性政策。這可讓開發人員根據要求的方式及用途,決定是否接受或拒絕要求,也可以只回應由自己應用程式提出的合理要求。

同源
由您自己的伺服器 (相同來源) 所提供網站發出的要求會繼續運作。 在 JavaScript 中,https://site.example 的資源 https://site.example/foo.json 擷取要求後,瀏覽器會傳送 HTTP 要求標頭「Sec Fetch-Site: same-origin」。
跨網站
由於 Sec-Fetch-* 標頭提供的 HTTP 要求中添加了額外的背景資訊,因此伺服器可能會拒絕惡意的跨網站要求。 如果 https://evil.example 上的圖片將 img 元素的 src 屬性設為「https://site.example/foo.json」,會導致瀏覽器傳送 HTTP 要求標頭「Sec-Fetch-Site: cross-site」。

Sec-Fetch-Site

瀏覽器支援

  • 76
  • 79
  • 90
  • 16.4

資料來源

Sec-Fetch-Site 會告知伺服器傳送要求的「網站」。瀏覽器會將這個值設為下列其中一個值:

  • same-origin,如果要求是由您自己的應用程式所發出 (例如 site.example)
  • same-site:如果要求來自您網站的子網域 (例如 bar.site.example)
  • none:如果要求是因使用者與使用者代理程式的互動而明確引起 (例如按下書籤)
  • cross-site,如果要求是由其他網站 (例如 evil.example) 傳送

Sec-Fetch-Mode

瀏覽器支援

  • 76
  • 79
  • 90
  • 16.4

資料來源

Sec-Fetch-Mode 表示要求的「模式」。這大致對應到要求的類型,並可讓您區分資源載入作業和導覽要求。舉例來說,navigate 的目的地代表頂層導覽要求,而 no-cors 則代表載入圖片等資源要求。

Sec-Fetch-Dest

瀏覽器支援

  • 80
  • 80
  • 90
  • 16.4

資料來源

Sec-Fetch-Dest 會公開要求的目的地 (例如 scriptimg 標記導致瀏覽器要求資源)。

如何使用擷取中繼資料來防範跨來源攻擊

這些要求標頭提供的額外資訊相當簡單,但是額外的內容可讓您在伺服器端建立強大的安全性邏輯 (也稱為「資源隔離政策」),只需要幾行程式碼。

實作資源隔離政策

資源隔離政策可防止外部網站要求存取您的資源。封鎖這類流量可降低常見的跨網站網路漏洞,例如 CSRF、XSSI、時間攻擊和跨來源資訊外洩。您可以為應用程式的所有端點啟用這項政策,並允許來自您自己的應用程式,以及直接導覽 (透過 HTTP GET 要求) 的所有資源要求。應該在跨網站情境中載入的端點 (例如使用 CORS 載入的端點) 可以選擇不採用這個邏輯。

步驟 1:允許不會傳送擷取中繼資料的瀏覽器要求

由於並非所有瀏覽器都支援擷取中繼資料,因此如要允許未設定 Sec-Fetch-* 標頭的要求,請檢查 sec-fetch-site 是否存在。

if not req['sec-fetch-site']:
  return True  # Allow this request

步驟 2:允許相同網站和瀏覽器發出的要求

系統會允許任何不來自跨來源結構定義 (例如 evil.example) 的要求。具體來說,這些要求具有以下特性:

  • 來自您自己的應用程式 (例如同源要求中,site.example 一律允許 site.example/foo.json 要求)。
  • 源自您的子網域。
  • 是由使用者和使用者代理程式的互動 (例如直接瀏覽,或是按一下書籤等) 所引起。
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
  return True  # Allow this request

步驟 3:允許簡易的頂層導覽和頁框

為確保使用者在其他網站仍可連結您的網站,您必須允許簡單的頂層導覽 (HTTP GET)。

if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
  # <object> and <embed> send navigation requests, which we disallow.
  and req['sec-fetch-dest'] not in ('object', 'embed'):
    return True  # Allow this request

步驟 4:選擇不採用用於提供跨網站流量流量的端點 (選用)

在某些情況下,應用程式可能會提供需跨網站載入的資源。這些資源必須是個別路徑或每個端點的豁免項目。這類端點的範例如下:

  • 要跨來源存取的端點:如果應用程式提供的端點已啟用 CORS,您必須明確將其停用資源隔離功能,以確保仍能對這些端點向這些端點發出跨網站要求。
  • 公開資源 (例如圖片、樣式等):任何應從其他網站跨來源載入的公開和未經驗證資源也可以豁免。
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
  return True

步驟 5:拒絕跨網站及無法瀏覽的所有其他要求

這項資源隔離政策將會拒絕任何其他的 cross-site 要求,藉此保護您的應用程式免受常見的跨網站攻擊。

範例:以下程式碼示範如何在伺服器上完整實作一個完善的資源隔離政策,或作為中介軟體,拒絕潛在的惡意跨網站資源要求,同時允許簡單的瀏覽要求:

# Reject cross-origin requests to protect from CSRF, XSSI, and other bugs
def allow_request(req):
  # Allow requests from browsers which don't send Fetch Metadata
  if not req['sec-fetch-site']:
    return True

  # Allow same-site and browser-initiated requests
  if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
    return True

  # Allow simple top-level navigations except <object> and <embed>
  if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
    and req['sec-fetch-dest'] not in ('object', 'embed'):
      return True

  # [OPTIONAL] Exempt paths/endpoints meant to be served cross-origin.
  if req.path in ('/my_CORS_endpoint', '/favicon.png'):
    return True

  # Reject all other requests that are cross-site and not navigational
  return False

部署資源隔離政策

  1. 安裝上述程式碼片段等模組,即可記錄及監控網站的行為,並確保這些限制不會影響任何正常的流量。
  2. 藉由排除合法的跨來源端點,修正潛在違規情形。
  3. 捨棄不符合規定的要求,強制執行政策。

找出並修正政策違規問題

建議您先在伺服器端程式碼的報表模式中啟用政策,以沒有任何連帶效果的方式測試政策。或者,您也可以將這個邏輯導入中介軟體,或透過反向 Proxy 記錄您的政策可能在套用至實際工作環境流量時產生的任何違規事項。

從我們推出 Google 擷取中繼資料資源隔離政策的經驗,大部分應用程式預設可相容於此類政策,而且很少要求排除端點才能允許跨網站流量。

強制執行資源隔離政策

確認政策不會影響合法的正式環境流量後,即可強制執行限制,確保其他網站無法要求你的資源,也無法保護使用者免於跨網站攻擊。

其他資訊