Tác giả: imToken
Một bot MEV từ lâu săn lùng những nhà giao dịch phổ thông trên Ethereum, cuối cùng cũng rơi vào một cái bẫy "tùy chỉnh" trị giá 7,5 triệu đô la.
Ngày 21 tháng 6, Jaredfromsubway.eth, một bot sandwich arbitrage nổi tiếng trên Ethereum đã bị tấn công, các tài sản như WETH, USDC trong địa chỉ bị chuyển đi, thống kê sơ bộ thiệt hại hơn 7,5 triệu đô la (tuy nhiên hiện vẫn có sự khác biệt trong thông tin thiệt hại được công bố).
Điều thú vị là cuộc tấn công này không phải do lộ khóa riêng tư, cũng không khai thác lỗ hổng hợp đồng thông minh theo nghĩa truyền thống, mà là kẻ tấn công triển khai trước một số lượng lớn token giả, nhóm thanh khoản và hợp đồng phụ trợ, đóng gói chúng thành các đường giao dịch có khả năng tồn tại cơ hội chênh lệch giá, dụ bot trong quá trình thực thi tự động cấp phép Approval ERC-20 cho hợp đồng độc hại, cuối cùng "hợp pháp" chuyển đi tài sản của bot MEV này.
Tính đến thời điểm đăng bài, Jaredfromsubway.eth đã công khai nhắn tin trên blockchain tới kẻ tấn công, nói rằng "nếu trong vòng 48 giờ trả lại 2150 ETH, sẵn sàng trả một nửa tiền thưởng whitehat, nếu không sẽ áp dụng mọi biện pháp pháp lý và thi hành khả thi để truy cứu trách nhiệm".
Tuy nhiên, ngay cả bot MEV chuyên nghiệp cao được vận hành bằng mã cũng vấp phải Approval, điều này cũng khiến người ta phải nhìn nhận lại, động tác "Approval" mà chúng ta sử dụng hàng ngày này, thực sự ẩn chứa nguy hiểm lớn đến mức nào?
1. Một cuộc vây bắt ngược được thiết kế riêng cho bot MEV
Nếu phân tích kỹ sự kiện tấn công này, sẽ thấy đây không phải là một lỗ hổng được kích hoạt ngẫu nhiên, mà là một cuộc vây bắt lâu dài nhắm vào logic giao dịch được thiết kế của Jaredfromsubway.eth.
Jaredfromsubway.eth từ lâu đã là một trong những bot sandwich arbitrage nổi tiếng nhất trên Ethereum. Cái gọi là tấn công sandwich, nói đơn giản, chính là khi bot phát hiện một giao dịch trên chuỗi sắp xảy ra, sẽ mua vào trước người dùng, đẩy giá tăng; sau khi người dùng hoàn thành giao dịch với giá xấu hơn, lập tức bán ra, kiếm lời từ chênh lệch giá.
Cũng chính vì vậy, chiến lược này yêu cầu bot liên tục quét giao dịch trên chuỗi, với tốc độ cực nhanh để đánh giá cơ hội chênh lệch giá, và tổ chức đường giao dịch, gọi các token và hợp đồng khác nhau, điều này cũng có nghĩa là tốc độ càng nhanh, bao phủ càng nhiều tài sản và giao thức, cơ hội bot có thể nắm bắt cũng càng nhiều.
Nhưng chính điểm này đã trở thành điểm đột phá trong sự kiện lần này.
Theo phân tích sau sự kiện, kẻ tấn công không trực tiếp tấn công hợp đồng tiền của bot, mà đã dành vài tuần để xây dựng một môi trường giao dịch trông có vẻ có thể sinh lời:
- Bước đầu tiên, là triển khai một số lượng lớn token và nhóm thanh khoản giả. Những token này mô phỏng WETH, USDC, USDT và các tài sản phổ biến khác về tên giao diện, hành vi giao dịch, khiến hệ thống nhận dạng tự động của bot nhầm tưởng phát hiện đường giao dịch bình thường;
- Bước thứ hai, là dần dần giành được sự tin tưởng của bot. Trong các bài kiểm tra ban đầu, quyền được cấp của bot được sử dụng bình thường cùng với giao dịch, sau khi hệ thống của bot bắt đầu lặp lại thực thi các đường tương tự, kẻ tấn công điều chỉnh logic hợp đồng, khiến một số quyền được cấp mà bot tạo ra không bị tiêu hao thực tế, cũng không về 0 sau khi giao dịch kết thúc, dẫn đến những quyền này vẫn còn đó;
- Cuối cùng, kẻ tấn công tập trung gọi hạn mức quyền vẫn còn hiệu lực, chuyển WETH, USDC và USDT thật trong hợp đồng bot ra ngoài;
Nói thẳng ra, toàn bộ cuộc tấn công nhắm hoàn toàn vào đặc điểm vận hành của bot MEV, tức là trước tiên tạo ra một môi trường phù hợp với quy tắc đánh giá lợi nhuận của nó, sau đó lợi dụng cơ chế theo đuổi thực thi tự động đường giao dịch của nó, khiến hệ thống chủ động giao quyền gọi tài sản.
Điều này cũng giải thích tại sao ngay cả bot MEV chuyên nghiệp cao cũng bị dính đòn.
Nó biết cách tính chênh lệch giá, chi phí Gas và thứ tự giao dịch, nhưng chưa chắc sẽ xác minh danh tính đầy đủ cho mỗi hợp đồng mới xuất hiện, từ góc độ này, vấn đề của người dùng phổ thông là "xác nhận mà không hiểu", vấn đề của bot tự động là "tự động thực thi mà không xác nhận".
Bề ngoài, hai cái hoàn toàn khác nhau, nhưng rủi ro cốt lõi lại khá gần, bởi vì họ đều coi việc ủy quyền như một bước thông thường trước khi hoàn thành giao dịch, mà không nhận thức rõ ràng mức độ nguy hiểm tiềm ẩn của nó cao đến mức nào.
2. Tại sao Approval luôn bị đánh giá thấp?
Như đã biết, trong tiêu chuẩn ERC-20 của Ethereum và các chuỗi tương thích EVM, Approve (ủy quyền) là một thiết kế khá cơ bản.
Tuy nhiên, khi người dùng chuyển tiền trực tiếp trong ví, thường gọi là transfer, thường không liên quan đến Approve, chỉ trong các tình huống hợp đồng thông minh như DEX, cho vay, staking hoặc thêm thanh khoản, người dùng mới cần để hợp đồng thông minh đại diện mình gọi token, lúc đó mới liên quan đến Approval.
Ví dụ, khi chúng ta muốn đổi USDT lấy ETH trên Uniswap, hợp đồng thông minh của Uniswap không thể trực tiếp vào ví của bạn lấy USDT, trước tiên phải thực hiện một lần Approve để nói với hệ thống "tôi cho phép Uniswap rút X USDT trong ví của tôi".
Chỉ sau khi ủy quyền hoàn tất, hợp đồng có được quyền mới có thể thông qua transferFrom, trong hạn mức được phép, gọi USDT của người dùng, việc Swap tiếp theo mới có thể hoàn thành.
Nghĩa là, bản thân Approval không phải là lỗ hổng, mà là nền tảng quan trọng để DeFi có thể vận hành bình thường. Chỉ có điều, vấn đề là nó hơi giống quyền trừ tiền tự động của Alipay/WeChat:
Người dùng không giao mật khẩu tài khoản cho cửa hàng, nhưng cho phép cửa hàng chủ động trừ tiền trong phạm vi thỏa thuận, chỉ cần ủy quyền vẫn còn hiệu lực, việc trừ tiền sau đó không cần người dùng nhập lại mật khẩu hay xác nhận từng giao dịch, điều này tự nhiên mang lại một số vấn đề.
Đầu tiên là vấn đề ủy quyền vô hạn, mọi người thường biến một giao dịch thành quyền lâu dài. Chủ yếu để giảm thao tác và chi phí Gas do ủy quyền lặp lại, nhiều DApp sẽ mặc định yêu cầu một hạn mức ủy quyền cực lớn, cũng chính là "ủy quyền vô hạn" thường thấy.
Người dùng ban đầu có thể chỉ muốn dùng 100 USDC để hoàn thành một giao dịch, nhưng lại cho phép hợp đồng sử dụng toàn bộ USDC trong địa chỉ của mình trong tương lai. Chỉ cần ủy quyền đó chưa bị hủy, ngay cả khi ví của người dùng lúc đó chỉ có ít tài sản, USDC được chuyển vào lại trong tương lai cũng có thể tiếp tục bị ảnh hưởng.
Thứ hai là ủy quyền mặc định sẽ không biến mất khi rời khỏi DApp. Nhiều người dùng nhầm lẫn "ngắt kết nối ví" và "thu hồi ủy quyền", thực tế, ngắt kết nối chỉ khiến trang web tạm thời không thể đọc hoặc yêu cầu ví hiện tại, không thay đổi Approval đã ghi vào blockchain.
Đóng trang web, xóa DApp, xóa cache trình duyệt, thậm chí thay đổi ứng dụng ví, đều không làm nó tự động mất hiệu lực.
Cuối cùng, ngay cả hợp đồng bình thường, cũng có thể trở nên nguy hiểm trong tương lai. Bởi vì nhiều rủi ro ủy quyền không chỉ đến từ trang web giả mạo độc hại ngay từ đầu, giống như cuộc vây bắt lần này, người dùng có thể cấp quyền cho một giao thức bình thường lúc đó, nhưng sau đó hợp đồng giao thức bị tấn công, khóa quản trị bị rò rỉ, logic có thể nâng cấp bị thay thế, hoặc hợp đồng định tuyến mà nó gọi gặp vấn đề.
Đối với người dùng, tài sản vẫn nằm trong địa chỉ của mình, nhưng từ góc độ quyền hạn, một hợp đồng khác luôn có khả năng gọi những tài sản này. Do đó, rủi ro Approval không chỉ là "tôi có ủy quyền cho kẻ xấu không", mà còn bao gồm "đối tượng tôi ủy quyền sau này có gặp vấn đề không".
3. Vậy làm thế nào để quản lý rủi ro Approval
Đối mặt với rủi ro Approval, đề xuất đơn giản nhất là "không ủy quyền vô hạn".
Nhưng trong môi trường sử dụng DeFi thực tế, hoàn toàn từ chối ủy quyền là không thực tế, như đã nói ở trên, bản thân ủy quyền không phải là lỗ hổng, nó là cách cơ bản để ứng dụng trên chuỗi gọi tài sản.
Điều thực sự cần thay đổi, là biến Approval từ một hành động xác nhận một lần, thành một cơ chế quản lý quyền liên tục.
Vậy đối với người dùng phổ thông, trước tiên cần hình thành một số thói quen cơ bản:
- Thứ nhất, tuân theo nguyên tắc "quyền tối thiểu". Khi ví hiện lên cảnh báo ủy quyền, cố gắng đặt hạn mức theo nhu cầu thực tế của lần tương tác này, ví dụ chỉ chuẩn bị dùng 100 USDT, cố gắng chỉ ủy quyền hạn mức gần 100 USDT, thay vì mở trực tiếp quyền vô hạn;
- Thứ hai, phân biệt ví lưu trữ và ví tương tác. Địa chỉ lưu trữ tài sản lớn dài hạn, cố gắng không kết nối thường xuyên với DApp lạ; khi tham gia airdrop, Mint, dự án mới và tương tác DeFi rủi ro cao, có thể sử dụng địa chỉ riêng biệt, giới hạn tổn thất tiềm ẩn trong phạm vi nhỏ hơn;
- Thứ ba, kiểm tra định kỳ và thu hồi quyền không còn cần thiết. Người dùng có thể thông qua các công cụ như Revoke.cash, hoặc trong imToken vào trang token tương ứng, nhấp vào "Token Function" ở góc dưới bên trái, sau đó chọn "Quản lý ủy quyền", xem đối tượng ủy quyền, token và hạn mức của địa chỉ đó, và khởi động thu hồi đối với quyền không còn sử dụng hoặc không rõ nguồn gốc (đọc thêm 《Hướng dẫn chi tiết sử dụng Revoke.cash để quản lý ủy quyền》);
Tất nhiên, nói ngàn lời vạn lời, đối mặt với các cuộc tấn công ủy quyền khó lường, chỉ dựa vào ý thức an toàn của người dùng và kiểm tra định kỳ vẫn chưa đủ, bởi hầu hết người dùng khó phân biệt một chuỗi địa chỉ hợp đồng thuộc về ai, cũng khó đánh giá một hạn mức ủy quyền có hợp lý hay không.
Vậy với tư cách là hào thành đầu tiên bảo vệ người dùng bước vào Web3, ví phải cung cấp khả năng phòng thủ chủ động về khả năng sản phẩm.
Lấy imToken làm ví dụ, sẽ đánh dấu hoặc chặn các token, địa chỉ và DApp rủi ro đã được nhận dạng, khi người dùng cấp quyền token cho tài khoản bên ngoài thông thường, hoặc chuyển tiền trực tiếp đến địa chỉ hợp đồng, cũng sẽ cung cấp cảnh báo rủi ro có mục tiêu, những cảnh báo này không thể thay thế đánh giá của người dùng, nhưng ít nhất có thể thêm một lớp đệm an toàn cần thiết trước khi thực sự ký.
Ngoài ra, imToken còn trong các khâu quan trọng như đăng nhập DApp, chuyển tiền, đổi token và ủy quyền, phân tích cấu trúc và hiển thị dễ đọc nội dung ký, cố gắng giúp người dùng hiểu mình đang đồng ý với điều gì trước khi xác nhận, đảm bảo nội dung người dùng ký phải nhất quán với hành vi họ nhìn thấy, thay vì bị nén thành một chuỗi dữ liệu hash khó nhận biết.
Với sự tiến triển hơn nữa của các tiêu chuẩn Clear Signing như ERC-7730, việc hiển thị dễ đọc "thấy gì ký đó (What You See Is What You Sign)" này, cũng có hy vọng từ khả năng sản phẩm của một ví đơn lẻ, dần trở thành tiêu chuẩn ngành được chia sẻ giữa ví, DApp và hợp đồng thông minh.
Nhìn chung, khóa riêng tư quyết định ai sở hữu tài khoản, Approval quyết định ai còn có thể gọi tài sản trong tài khoản, hai cái không phải một, nhưng quan trọng như nhau.
Điều này cũng có nghĩa, an toàn ví không thể chỉ dừng lại ở "khóa riêng tư có bị rò rỉ không", và điều này cần nỗ lực chung từ người dùng đến ví: đối với người dùng, cần xem rõ đối tượng và hạn mức trước khi ủy quyền, kịp thời dọn dẹp quyền không còn cần thiết sau khi tương tác kết thúc; đối với ví, cần làm cho những quyền vốn ẩn trong hợp đồng trở nên dễ thấy hơn, dễ hiểu hơn, cũng dễ bị giới hạn và thu hồi hơn.
Rốt cuộc, thứ thực sự nguy hiểm chưa chắc là giao dịch chuyển tiền vừa xảy ra, mà cũng có thể là một quyền đã bị lãng quên từ lâu, nhưng vẫn chưa bao giờ mất hiệu lực.













