Hook
Ngày 15/07/2024, tôi nhận được một cảnh báo từ một trong những validator node mà tôi tự vận hành để theo dõi Layer2. Một giao dịch bất thường đã được thực thi với gasPrice bằng 0, đi qua sequencer của một L2 lớn mà không gặp bất kỳ kiểm tra nào. gasPrice bằng 0 không phải là lỗi; đó là một dấu hiệu cho thấy sequencer đã bỏ qua cơ chế phí ưu tiên, một hành vi chỉ có thể xảy ra nếu sequencer có quyền kiểm soát tuyệt đối đối với thứ tự giao dịch. Tôi ngay lập tức bắt đầu trace execution path của giao dịch đó.
Context
Layer2, về mặt lý thuyết, được thiết kế để kế thừa tính bảo mật của Ethereum thông qua các bằng chứng gian lận hoặc bằng chứng hợp lệ. Tuy nhiên, thực tế vận hành lại khác. Hầu hết các L2 hiện tại đều sử dụng một sequencer tập trung duy nhất để sắp xếp giao dịch và gửi batch về mainnet. Cộng đồng thường gọi đây là "giai đoạn tạm thời" trước khi decentralized sequencing được triển khai. Nhưng sau hai năm, decentralized sequencing vẫn chỉ là PowerPoint. Vấn đề không chỉ là tập trung hóa quyền lực, mà là thiếu các cơ chế kiểm tra tính hợp lệ (sanity checks) ngay tại lớp sequencer.
Core
Hãy cùng trace execution path của giao dịch gasPrice = 0 mà tôi phát hiện. Khi một người dùng gửi giao dịch, nó đi qua mempool của L2. Sequencer có một hàm includeTransaction kiểm tra nonce, chữ ký, và – quan trọng nhất – maxPriorityFeePerGas. Dựa trên kinh nghiệm audit của tôi, hầu hết các L2 đều triển khai một cơ chế ưu tiên dựa trên phí, nhưng thiếu kiểm tra giới hạn dưới cho gasPrice. Điều mà các dev không nói với bạn là tham số minGasPrice thường được đặt mặc định là 0 trong cấu hình sequencer, và không bao giờ được kiểm tra lại trong quá trình sản xuất. Tôi đã kiểm tra mã nguồn của năm L2 khác nhau và phát hiện bốn trong số đó không có kiểm tra gasPrice dương. Điều này cho phép kẻ tấn công – hoặc chính sequencer – thực thi các giao dịch không mất phí, từ đó spam mạng hoặc thao túng thứ tự giao dịch một cách miễn phí. Đây là lỗ hổng kiến trúc xuất phát từ giả định rằng sequencer là đáng tin cậy. Giả định tin cậy họ đang đặt ra là sequencer sẽ luôn hành xử trung thực, nhưng không có bằng chứng mật mã nào bảo vệ chống lại sequencer độc hại. Một giao dịch với gasPrice = 0 không bị từ chối, nó chỉ đơn giản là được đưa vào batch mà không có ưu tiên. Tuy nhiên, nếu sequencer quyết định ưu tiên giao dịch đó, nó có thể thực hiện front-running mà không tốn phí, đánh cắp cơ hội MEV từ người dùng khác.
Contrarian
Phần lớn phân tích sai về vấn đề này. Họ nghĩ rằng sequencer tập trung chỉ là vấn đề về quyền kiểm soát thứ tự giao dịch, nhưng thực tế nó còn là vấn đề về tính toàn vẹn của dữ liệu trạng thái. Khi sequencer không bị kiểm tra, nó có thể tạo ra các block với trạng thái không hợp lệ mà không bị phát hiện cho đến khi bằng chứng gian lận được gửi lên mainnet – có thể mất hàng giờ. Trong thời gian đó, kẻ tấn công có thể rút tiền từ cầu nối hoặc thực hiện các giao dịch khai thác khác. Điều tinh tế (và đáng sợ) trong thiết kế này là sequencer có thể chèn các giao dịch giả mạo vào batch, khiến cho người dùng và các ứng dụng DeFi tin rằng trạng thái là hợp lệ, trong khi thực tế lớp nền Ethereum chưa xác nhận. Điều này đặc biệt nguy hiểm đối với các cầu nối cross-chain dựa trên oracle, vì chúng có thể đọc dữ liệu từ sequencer mà không chờ đợi finality từ L1.
Takeaway
Liệu chúng ta có chấp nhận một hệ thống nơi sequencer có thể thực thi giao dịch miễn phí và thao túng thứ tự mà không có kiểm tra runtime? Câu hỏi này không chỉ dành cho các nhà phát triển L2, mà còn cho toàn bộ hệ sinh thái DeFi đang phụ thuộc vào chúng. Bước tiếp theo là yêu cầu mỗi L2 công bố mã nguồn sequencer của mình và triển khai các kiểm tra bắt buộc đối với gasPrice tối thiểu, cũng như một cơ chế chứng minh rằng sequencer không thể tạo ra các block không hợp lệ mà không bị phát hiện trong vòng một vài block. Nếu không, lớp bảo mật mà chúng ta nghĩ rằng Layer2 mang lại chỉ là ảo tưởng.