Exploiting The Off-Chain Ecosystem In Web 3 Bug Bounty by Bruno Halltari | BBV, DEF CON 33
三句話摘要
Web3 應用中的鏈外漏洞利用:從 XSS 繞過到 OAuth 劫持的實戰案例 Web3 Bug Bounty 獵人不應忽視鏈外層面,特別是前端安全(XSS 繞過)和認證漏洞(OAuth 配置遺留),這些往往能導致高影響的賬戶接管和資金風險。 HTML 編輯器的多層繞過鏈:開發者使用 sanitizeURL 進行簡單過濾(移除 JavaScript URI 和 HTML entities),但未考慮 Blob protocol;即便升級到 DOMPurify,因缺乏嚴格的型別檢驗,仍可透過傳入物件而非字串來繞過 isValidAttribute 驗證,達成首次 XSS。
重點整理
重點- 1
HTML 編輯器的多層繞過鏈:開發者使用 sanitizeURL 進行簡單過濾(移除 JavaScript URI 和 HTML entities),但未考慮 Blob protocol;即便升級到 DOMPurify,因缺乏嚴格的型別檢驗,仍可透過傳入物件而非字串來繞過 isValidAttribute 驗證,達成首次 XSS。
- 2
Prototype Pollution 作為二階漏洞放大器:lodash 的 cloneDeep 函數在原型鏈上添加方法,攻擊者可污染 String.prototype;結合 React 的屬性驗證邏輯漏洞,最終在被允許的 defaultProps 中注入被禁用的 `is` 屬性,實現第三階段 XSS。
- 3
開發測試配置的線上遺留:許多 Web3 應用在 Google OAuth 中保留 localhost 作為 redirect_uri 用於本機測試,開發者誤認為不可利用;但移動應用無需權限即可啟動本機 web server,使得 localhost 成為實際可攻擊面。
- 4
OAuth 流程中的自動登入繞過:GSI(Google Sign-In)提供的 autoselect 參數可跳過使用者交互確認,配合被污染的 origin 和 redirect_uri,攻擊者可在 iframe 中無聲地完成完整認證流程並竊取 JWT token。
實用技巧與重點
乾貨- 相關庫與工具:
- sanitizeURL(第三方驗證庫)
- DOMPurify(HTML 清理庫)
- lodash 的 cloneDeep(含有 prototype 污染風險)
- 漏洞所在應用:
- AcreProof 的 NearWeb(HTML editor + widget 功能)
- 支援 Google OAuth 的多個 Web3 交易所/平台
- 技術指標:
- 第一案例:Blob URI (`blob://`) 繞過、DOMPurify object-based bypass、prototype pollution via cloneDeep、React `is` 屬性注入
- 第二案例:localhost redirect_uri 允許、GSI autoselect 參數、origin 污染、JWT token 竊取
- 漏洞回報平台:
- Immunefi
- HackerOne(Web3 應用較少)
- Hackerproof
- Munify
- 獎金實績:
- 第一案例(NearWeb XSS):中等獎金級別
- 第二案例(OAuth 劫持):$5,000 USD
結論
結論“Web3 Bug Bounty 獵人不應忽視鏈外層面,特別是前端安全(XSS 繞過)和認證漏洞(OAuth 配置遺留),這些往往能導致高影響的賬戶接管和資金風險。”
完整解析
詳細Bruno 是 Ottersec 的安全研究員,在這場演講中分享了他在 Web3 應用漏洞獵人工作中發現的兩個重大鏈外漏洞案例。他開場指出,許多 Bug Bounty 獵人傾向於只關注鏈上漏洞,但實際上 Web3 應用的鏈外層面(前端、認證、API)仍存在大量可利用的安全缺陷。
第一個案例來自 AcreProof 的 NearWeb 應用,該應用提供了一個 HTML 編輯器讓用戶建立 widgets,所有 HTML 內容都被放在沙箱中。Bruno 發現開發團隊使用 sanitizeURL 函數來清理 HREF 屬性,該函數嘗試移除 JavaScript URI、HTML entities、空格並驗證協議只能是 HTTP/HTTPS 或安全協議如 `mailto:`。然而他發現可以使用 Blob URI 繞過此限制,因為 Blob 本質上是原始檔案系統,可以包含任意 HTML。這是第一層繞過。開發者發現後改用 DOMPurify 庫來替代,但新實現仍有漏洞:DOMPurify 的 isValidAttribute 函數雖然檢查屬性是否安全,但使用了字串替換操作,導致當傳入物件而非字串時會產生型別混淆。Bruno 利用這點構造了一個物件,先傳入 DOMPurify 認可的 `mailto:` 協議以通過驗證,隨後返回 `javascript:` URI,成功第二層繞過。
第三層繞過涉及更深層的 Prototype Pollution 攻擊。React 中有一個特殊的 `is` 屬性用來定義自訂元素,但開發者已禁用它。Bruno 發現程式碼中使用了 lodash 的 cloneDeep 函數,該函數會在原型鏈上添加方法。透過精心構造的輸入,他污染了 String.prototype,最終使得 React 的屬性驗證邏輯在遍歷 defaultProps 時引入被污染的 `is` 屬性。由於 React 認為這是一個自訂元素,便不會清理 onerroraller 和 document.domain 等惡意屬性,從而實現 XSS。這個漏洞導致了賬戶接管,而 Bruno 強調在 Web3 環境中,通過簽交易提示等互動方式能證明更高的影響力,這對 Bug Bounty 回報至關重要。
第二個案例涉及 Google OAuth 的 localhost 允許名單漏洞。Bruno 發現許多 Web3 應用允許在認證流程中使用 localhost 作為重新導向 URI,開發者通常在測試時添加此項但忘記移除。根據 OWASP 移動安全 Top 10,所有移動應用都可以啟動本機 web server 而無需特殊權限,因此 localhost 並非不可攻擊。他展示了兩種流程:非 GSI 流程較簡單,直接在重新導向 URI 中放入 localhost 並從 location.hash 或 location.search 中提取 token;GSI 流程較複雜,需要同時污染 redirect_uri 和 origin 參數。關鍵技巧是利用 GSI 提供的 autoselect 參數來自動化登入流程,繞過用戶交互確認。Bruno 的最終利用方法是在本機 web server 中開啟 iframe,向認證端點發送 client_id 和被污染的 origin,透過自動選擇和信息發送獲取 JWT token,整個過程對目標用戶完全無聲。這個漏洞在某交易所被回報後獲得 $5,000 的獎金。
關鍵時刻
Pipeline v2帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。
事實查核
Pipeline v2說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。


