- Nhà nghiên cứu Vipul Sahu công bố lỗ hổng Reflected XSS qua hash fragment trên connect.trezor.io — cho phép chạy JS tùy ý dưới origin trusted của Trezor Connect.
- Phân tích kỹ thuật, kịch bản tấn công, và vì sao hardware wallet vẫn là lớp phòng thủ cuối.
TL;DR
Ngày 25/03/2026, Trezor công bố một advisory Reflected XSS trên connect.trezor.io — domain trusted mà hàng chục ví phần mềm và dApp nhúng qua iframe để giao tiếp với thiết bị Trezor. Lỗ hổng do researcher Vipul Sahu (@GodSpeed000123) báo cáo: một tham số URL được đọc từ hash fragment rồi bơm thẳng vào DOM mà không sanitize, cho phép chạy JavaScript tùy ý dưới origin của Trezor. Patch đã triển khai, nhưng bài học về surface area và threat model thì còn nguyên.
Chuyện gì vừa xảy ra
Advisory được Trezor đăng công khai với tiêu đề "Reflected cross-site scripting (XSS) vulnerability on connect.trezor.io via hash fragment script injection". Điểm vào là một trang documentation trên subdomain connect.trezor.io. Trang này đọc dữ liệu người dùng điều khiển từ location.hash (phần sau dấu # trong URL) và ghi vào DOM mà không qua escape/sanitize — một sink XSS cổ điển nhưng vẫn len lỏi được qua review.
Khác với reflected XSS truyền thống (server trả lại payload trong response HTML), biến thể này DOM-based: hash fragment không được gửi lên server, nên WAF, log phía backend, và các pipeline CSP-report tập trung vào request thường không bắt được. Chỉ có audit tĩnh hoặc instrumentation client-side mới phát hiện ra.
Vì sao lỗ hổng này đáng chú ý
connect.trezor.io không phải một website bình thường. Đây là trust anchor được nhúng vào luồng ký giao dịch của rất nhiều ví crypto — MetaMask, MyEtherWallet, các sàn tích hợp Trezor đều mở popup hoặc iframe từ origin này. Bất kỳ script nào chạy được trên origin đó đều có thể:
postMessagetới iframe Connect và giả lập phản hồi từ thiết bị.- Đọc/ghi
localStoragesame-origin của Trezor Connect. - Phủ overlay giả mạo (ví dụ form "nhập recovery seed") lên trên một domain mà người dùng đã được dạy là an toàn.
Nói cách khác: URL trông đúng hoàn toàn (https://connect.trezor.io/..., cert hợp lệ), user kiểm tra thanh địa chỉ và thấy "đúng rồi" — nhưng thứ chạy bên trong là code của attacker. Đây là cơn ác mộng cổ điển của phishing nhắm vào người dùng cẩn thận.
Chi tiết kỹ thuật
| Thuộc tính | Giá trị |
|---|---|
| Lớp lỗ hổng | Reflected / DOM-based XSS |
| Vector | URL hash fragment (#...) |
| Domain ảnh hưởng | connect.trezor.io |
| Tương tác người dùng | Cần click link crafted |
| Ngày công bố | 25/03/2026 |
| Reporter | Vipul Sahu (@GodSpeed000123) |
| Trạng thái | Đã patch |
Về mặt PoC: một URL dạng https://connect.trezor.io/<doc-path>#<payload> — với <payload> là chuỗi HTML/JS — đủ để kích hoạt execution khi trang load JavaScript đọc location.hash. Trezor không công bố chi tiết payload cụ thể (policy "fix first, details minimal"), nhưng class lỗi khớp hoàn toàn với pattern element.innerHTML = decodeURIComponent(location.hash.slice(1)) vốn xuất hiện khá nhiều trong code doc/demo viewer.
So với các lỗ hổng Trezor Connect trước đây
| Advisory | Năm | Vector | Mức độ |
|---|---|---|---|
| XSS in Trezor Connect (Gamer7112) | 2020-08 | XSS trong Connect library | Đã vá, ít chi tiết |
trezor-connect handleMessage XSS | 2020-09 | Injection qua postMessage, versions <8.1.12 | CVSS 5.4 (Medium) |
| XSS in Trezor Connect legacy versions (Jun Kokatsu) | 2022 | Endpoint deprecated /5, /6, /7 vẫn live | Re-exposure code cũ |
| Reflected XSS qua hash fragment | 2026-03 | DOM XSS từ location.hash trên trang docs | Đã vá |
Pattern rõ ràng: XSS cứ quay lại cùng một origin nhưng ở các sink khác nhau — từ message handler, tới URL deprecated, tới doc viewer. Bề mặt tấn công của một "thin bridge" subdomain lớn hơn tưởng tượng, đặc biệt khi team nào đó deploy thêm trang demo/docs lên cùng host để tiện routing.
Kịch bản tấn công thực tế
- Phishing seed phrase: attacker gửi link qua Discord/Telegram/email với anchor text dạng "Hướng dẫn khôi phục ví — trezor.io". Người dùng kiểm tra domain thấy khớp, click vào, script chèn form giả yêu cầu nhập 12/24 từ seed. Vì origin là trusted, mọi dấu hiệu cảnh báo đều im lặng.
- Address swap tại signing flow: dApp mở popup
connect.trezor.iođể lấy signature. Nếu session đã bị inject, script có thể hiển thị địa chỉ đích giả trên màn hình trình duyệt, hy vọng người dùng không đối chiếu với màn hình thiết bị Trezor. - Lateral move qua integrator: bất kỳ website nào iframe
connect.trezor.iođều có một kênhpostMessagecó thể bị thao túng, biến một XSS trên Trezor thành vấn đề trên mọi dApp đang tích hợp.
Giới hạn & chương trình bounty
Điểm sáng: Trezor xây threat model giả định "host có thể hoàn toàn malicious". Thiết bị Trezor luôn hiển thị địa chỉ đích và số tiền trên màn hình vật lý trước khi user bấm xác nhận. Người dùng có thói quen đối chiếu địa chỉ trên thiết bị vẫn không mất tiền kể cả khi host bị XSS. Seed phrase là chuyện khác — không bao giờ nên nhập seed vào bất kỳ website nào, kể cả connect.trezor.io.
Về bounty, Trezor áp dụng bảng tier cho Suite & Connect:
- Low:
$0 – $500 - Medium:
$500 – $1,000 - High:
$1,000 – $5,000 - Critical:
$5,000 – $20,000
XSS có khả năng chạm vào luồng ký thường rơi vào High tier vì device display đóng vai trò như một yếu tố thứ hai. Số tiền chính xác cho báo cáo của Vipul Sahu không được công bố. Thanh toán bằng Bitcoin qua Lightning hoặc on-chain theo tỷ giá tại thời điểm payout.
Bài học cho team bảo mật
- Audit mọi sink đọc
location.hash,location.searchtrên subdomain trust-critical. Hash fragment không đi tới server, nên review chỉ qua log/WAF là không đủ. - CSP nghiêm ngặt (
script-srckhông có'unsafe-inline') có thể chặn đứng DOM XSS dạng này ngay cả khi sink tồn tại. - Coi subdomain "bridge" như core product: trang docs, demo, status page cùng host với origin ký giao dịch là một quyết định kiến trúc cần review định kỳ — tách origin riêng là cách tốt nhất để giới hạn blast radius.
- Người dùng: quy tắc vàng vẫn là đối chiếu địa chỉ và số tiền trên màn hình thiết bị, không nhập seed vào bất kỳ website nào.
Nguồn: trezor.io/vulnerability, Trezor Bug Bounty Program, Snyk SNYK-JS-TREZORCONNECT-598796.
