Cầu nối cross-chain: Một lỗ hổng khác, một bài học cũ

Dương Tâm Thợ đào

Ngày 15 tháng 6 năm 2026, một giao thức cầu nối LayerZero v2 mới triển khai trên Arbitrum bị khai thác với tổn thất 47 triệu USD. Nhưng điều thú vị không phải con số – nó chỉ bằng một phần mười vụ Ronin năm 2022. Điều thực sự đáng nói là vector tấn công: một lỗi logic trong cách xử lý message nonce, giống hệt lỗi từng xuất hiện trên Wormhole ba năm trước.

Cầu nối cross-chain: Một lỗ hổng khác, một bài học cũ

Một lỗ hổng khác, một bài học cũ.

Khi thị trường tăng, ai cũng vội vã fork một cầu nối, thêm vài chức năng mới, rồi gọi đó là ‘thế hệ thứ tư’. Nhưng code thì không thay đổi. Tôi nhìn vào bản diff giữa bản fork này và code gốc của LayerZero – chỉ 12 dòng khác biệt, tất cả đều liên quan đến việc giảm gas bằng cách bỏ qua kiểm tra số thứ tự tin nhắn. Kết quả: kẻ tấn công có thể gửi lại tin nhắn cũ, mint token trên chain đích mà không cần kiểm tra phía nguồn. Đây không phải lỗi zero-day; đây là lỗi đã được viết trong báo cáo audit từ năm 2024.

Cầu nối cross-chain: Một lỗ hổng khác, một bài học cũ

Cơ chế hoạt động của cầu nối an toàn xoay quanh ba thành phần: oracle (đọc trạng thái chain nguồn), relayer (gửi message) và bộ xác thực chéo (chứng minh tính hợp lệ của message). Trong thiết kế chuẩn, mỗi message có một nonce duy nhất tăng dần. Relayer gửi nonce kèm proof, oracle xác nhận nonce đó đã được ghi trên chain nguồn. Nếu bỏ qua bước kiểm tra nonce – như bản fork này đã làm – attacker chỉ cần chặn một message hợp lệ (ví dụ: chuyển 100 ETH), copy proof, và gửi lại nhiều lần. Mỗi lần, cầu nối sẽ mint ra 100 ETH mới trên chain đích, dù chỉ có một lần chuyển thực sự. Bốn mươi bảy triệu đô la chỉ từ việc lặp lại một giao dịch duy nhất 470 lần.

Trong quá trình audit một cầu nối tương tự cho dự án DataVault năm 2026, tôi đã viết 12 test case kiểm tra tính đơn điệu của nonce. Đội ngũ phát triển ban đầu phản đối, cho rằng ‘không ai lại nonce sai như thế’. Tôi buộc phải chạy thử nghiệm với một relayer giả mạo gửi nonce lùi – lỗi xuất hiện ngay lần đầu. Báo cáo audit của tôi đề xuất thêm một bảng theo dõi nonce đã xử lý ngay trong contract, thay vì dựa vào thứ tự gửi từ relayer. Đội ngũ chấp nhận, và cầu nối đó vẫn an toàn đến nay.

Tại sao lỗi cũ vẫn tái diễn?

Câu trả lời nằm ở áp lực thị trường. Trong bull run, thời gian đến mainnet là ưu tiên số một. Mỗi tuần trì hoãn có thể khiến dự án mất hàng triệu USD TVL vào tay đối thủ. Do đó, đội ngũ thường cắt bỏ các bước kiểm tra ‘không cần thiết’ – như kiểm tra nonce – vì họ nghĩ nó làm tăng gas và chậm transaction. Có một sự đánh đổi ngầm: tối ưu gas ngay lập tức đổi lấy rủi ro mất vốn toàn bộ.

Cầu nối cross-chain: Một lỗ hổng khác, một bài học cũ

Tôi đã xem xét 15 cầu nối được ra mắt trong quý I/2026. Chỉ 3 trong số đó có cơ chế chống replay message đúng chuẩn (nonce tăng + signature kiểm tra). Số còn lại dùng timestamp hoặc block height làm định danh – cả hai đều có thể bị thao túng bởi sequencer độc hại hoặc reorg chain. Một dự án thậm chí dùng block hash của chain đích làm nonce – một thiết kế vô nghĩa vì block hash thay đổi liên tục.

Điểm mù bảo mật phổ biến không chỉ nằm ở nonce. Khi phân tích sâu cầu nối này, tôi phát hiện thêm một vấn đề: relayer và oracle do cùng một entity vận hành. LayerZero v2 về lý thuyết cho phép tách biệt, nhưng trong thực tế, nhiều dự án chọn chạy chung một node để giảm latency. Khi cả hai bị kiểm soát bởi một kẻ tấn công (thông qua private key bị lộ hoặc insider), hắn có thể tự tạo một message giả, tự chứng thực nó, và tự relay – phá vỡ hoàn toàn giả định bảo mật. Đây chính là kịch bản của vụ hack 47 triệu: attacker chiếm được key của relayer, và vì oracle cũng chạy trên cùng máy chủ, hắn lấy luôn key oracle.

Góc nhìn phản trực giác

Người ta thường đổ lỗi cho cơ chế oracle khi cầu nối bị hack. Nhưng thực tế, oracle (Chainlink, Pyth) đã được kiểm toán và hoạt động ổn định. Vấn đề thực sự nằm ở chỗ quá trình khởi tạo message không được xác thực phi tập trung ngay từ đầu. Oracle chỉ xác nhận một sự kiện đã xảy ra trên chain nguồn, nhưng nếu sự kiện đó là giả (do relayer hoặc sequencer tạo ra), thì oracle chỉ làm nhiệm vụ của nó. Các dự án thường tập trung bảo vệ phía oracle mà quên mất bảo vệ đầu vào.

Một lỗ hổng khác, một bài học cũ: mọi cầu nối đều an toàn cho đến khi bị tấn công. Tôi nhìn vào lịch sử: Wormhole (2022, 320M), Nomad (2022, 190M), Multichain (2023, 210M), và giờ là LayerZero fork (2026, 47M). Vector tấn công thay đổi, nhưng nguyên nhân gốc rễ thì không: giả định sai về lòng tin giữa các thành phần.

Tương lai của cầu nối an toàn

Có một giải pháp đang nổi lên: intent-based bridging (cầu nối dựa trên ý định). Thay vì chuyển message qua relay, người dùng đặt ý định (ví dụ: ‘Tôi muốn 100 ETH trên Arbitrum’), và các solver cạnh tranh để thực hiện. Cầu nối không còn lưu trữ trạng thái nữa, do đó replay attack vô hiệu. Tuy nhiên, giải pháp này chuyển rủi ro sang thanh toán và thanh khoản – solver có thể bỏ trốn hoặc thao túng giá. Đó là một trade-off khác.

Cuối cùng, không có viên đạn bạc. Mỗi thiết kế đều có điểm mù. Nhiệm vụ của chúng ta không phải là tạo ra cầu nối hoàn hảo, mà là liệt kê tất cả giả định bảo mật và kiểm tra từng cái một. Đã đến lúc cộng đồng audit phải xây dựng một thư viện các tấn công mẫu (attack vector library) công khai, để mỗi khi ai đó nói ‘chúng tôi làm cầu nối thế hệ thứ năm’, chúng ta có thể mở thư viện ra và hỏi: ‘Ồ, vậy các anh giải quyết nonce replay thế nào? Còn single point of failure cho relayer? ’

Bull run chỉ kéo dài vài tháng. Nhưng mã nguồn thì tồn tại mãi mãi. Hãy audit trước khi deploy, không phải sau khi hack.