Vượt qua Layer Zero

Jan 05 2023
Ngay từ khi bắt đầu L2BEAT, chúng tôi đã nỗ lực rất nhiều để phân tích và hiểu các rủi ro liên quan đến các giao thức L2. Chúng tôi nỗ lực hết mình để trở thành cơ quan giám sát độc lập, không thiên vị, hành động vì lợi ích cao nhất của người dùng và hệ sinh thái.

Ngay từ khi bắt đầu L2BEAT, chúng tôi đã nỗ lực rất nhiều để phân tích và hiểu các rủi ro liên quan đến các giao thức L2. Chúng tôi nỗ lực hết mình để trở thành cơ quan giám sát độc lập, không thiên vị, hành động vì lợi ích cao nhất của người dùng và hệ sinh thái. Chúng tôi không để sở thích cá nhân của mình đối với dự án hoặc nhóm tham gia cản trở. Đó là lý do tại sao chúng ta thường cần bật cảnh báo đỏ hoặc chỉ ra mối lo ngại của mình trong các giao thức khác nhau, mặc dù chúng ta đánh giá cao thời gian và công sức của các nhóm cụ thể dành cho dự án của họ. Việc sớm có các cuộc thảo luận liên quan đến bảo mật cho phép toàn bộ hệ sinh thái chuẩn bị tốt hơn cho các rủi ro tiềm ẩn và phản ứng sớm hơn với bất kỳ hành vi đáng ngờ nào.

Hôm nay chúng tôi muốn mở ra một cuộc tranh luận về các mô hình bảo mật được chia sẻ của các ứng dụng chuỗi chéo. Hiện tại, có hai cách tiếp cận: bảo mật được chia sẻ và bảo mật cho mỗi ứng dụng. Cái đầu tiên, bảo mật được chia sẻ, chẳng hạn, được sử dụng bởi tất cả các bản tổng hợp. Cái thứ hai, bảo mật cho mỗi ứng dụng, được sử dụng bởi các dự án “omnichain”. Ví dụ điển hình của một dự án như vậy là LayerZero.

Bảo mật được chia sẻ so với Bảo mật bị cô lập

Bằng bảo mật được chia sẻ, chúng tôi muốn nói rằng các mã thông báo hoặc ứng dụng cụ thể chạy trên một cơ sở hạ tầng nhất định không tự do chọn mô hình bảo mật của chúng. Thay vào đó, họ phải tuân theo bất kỳ yêu cầu bảo mật nào mà cơ sở hạ tầng áp đặt. Ví dụ: các bản tổng hợp lạc quan thường áp đặt khoảng thời gian cuối cùng là 7 ngày — các ứng dụng chạy trên các bản tổng hợp như vậy không thể đơn giản bỏ qua hoặc rút ngắn khoảng thời gian này. Nó có vẻ giống như một trở ngại, nhưng đó là một trở ngại được đặt ra vì một lý do. Nó cho phép cung cấp cho người dùng sự đảm bảo an toàn mà họ có thể mong đợi được giữ bởi bất kỳ ứng dụng nào họ đang sử dụng trong bản tổng hợp đó, bất kể chính sách bảo mật nội bộ của ứng dụng đó là gì. Ứng dụng chỉ có thể củng cố chính sách của các bản tổng hợp chứ không làm suy yếu chính sách đó.

Bằng cách bảo mật riêng biệt, chúng tôi muốn nói rằng mọi ứng dụng đều chịu trách nhiệm xác định tính bảo mật của mình, không bị hạn chế bởi cơ sở hạ tầng theo bất kỳ cách nào. Lúc đầu, nó có vẻ như là một ý tưởng tốt. Xét cho cùng, các nhà phát triển ứng dụng biết rõ nhất những biện pháp bảo mật mà ứng dụng có thể cần. Nhưng đồng thời, nó chuyển giao trách nhiệm đánh giá rủi ro liên quan đến chính sách bảo mật của mọi ứng dụng cho người dùng cuối. Hơn nữa, nếu các nhà phát triển ứng dụng được tự do lựa chọn chính sách ứng dụng của họ, thì họ cũng có thể chọn thay đổi chính sách đó bất cứ lúc nào họ muốn. Vì vậy, việc đánh giá rủi ro một lần cho mọi ứng dụng là chưa đủ, chúng nên được đánh giá mỗi khi chính sách của ứng dụng thay đổi.

Vấn đề

Chúng tôi cho rằng mô hình bảo mật biệt lập trong đó mỗi ứng dụng có thể tự do xác định chính sách bảo mật của mình gây ra những lo ngại nghiêm trọng về bảo mật. Trước hết, nó làm tăng rủi ro cho người dùng cuối, vì họ phải xác thực riêng các rủi ro có xu hướng với mọi ứng dụng mà họ định sử dụng.

Nó cũng làm tăng rủi ro cho các ứng dụng sử dụng mô hình như vậy. Bảo mật bị cô lập làm tăng thêm rủi ro liên quan đến thay đổi chính sách bảo mật — nếu kẻ tấn công thay đổi mô hình bảo mật cho ứng dụng, kẻ tấn công cũng có thể vô hiệu hóa nó, tạo khả năng rút tiền hoặc lạm dụng nó theo bất kỳ cách nào khác. Không có lớp bảo mật bổ sung nào ở trên cùng của ứng dụng để bảo vệ chống lại việc sử dụng sai mục đích.

Hơn nữa, với các chính sách bảo mật có thể thay đổi ngay lập tức bất cứ lúc nào, thực tế không thể giám sát các ứng dụng hàng ngày và thông báo cho người dùng về các rủi ro.

Chúng tôi thấy nó tương tự như khả năng nâng cấp của hợp đồng thông minh. Chúng tôi đã cảnh báo chống lại nó tại L2BEAT . Chúng tôi thông báo cho người dùng về các bản tổng hợp và cầu nối có cơ chế nâng cấp trong hợp đồng thông minh của họ, cũng như cơ chế chính xác điều chỉnh khả năng nâng cấp trong từng trường hợp. Điều này vốn đã khá phức tạp và với một mô hình bảo mật biệt lập, điều này sẽ nhân lên cho mọi ứng dụng, khiến cho việc theo dõi một cách hiệu quả gần như không thể.

Đó là lý do tại sao chúng tôi coi bản thân một mô hình bảo mật bị cô lập là một rủi ro bảo mật và chúng tôi mặc định coi mọi ứng dụng sử dụng mô hình như vậy là rủi ro cho đến khi được chứng minh ngược lại.

Kế hoạch

Chúng tôi quyết định kiểm tra các giả định của mình trong thế giới thực, trên mạng chính. Khung LayerZero được chọn cho thử nghiệm vì đây là một trong những giải pháp phổ biến nhất sử dụng bảo mật biệt lập làm cốt lõi. Chúng tôi đã triển khai mã thông báo đa chuỗi an toàn và sau đó, cấu hình bảo mật đã được cập nhật để cho phép rút mã thông báo độc hại. Mã của mã thông báo dựa trên các ví dụ do LayerZero cung cấp và rất giống hoặc giống hệt với nhiều mã thông báo và ứng dụng đa chuỗi khác được triển khai trong sản xuất.

Nhưng trước khi đi sâu vào chi tiết, chúng ta hãy xem sơ qua mô hình bảo mật LayerZero trông như thế nào.

Như sách trắng của LayerZero đã nêu rõ, "giao tiếp liên chuỗi không đáng tin cậy" của nó dựa vào hai tác nhân độc lập (nhà tiên tri và người chuyển tiếp) hành động cùng nhau để đảm bảo an toàn cho giao thức.

Như LayerZero tuyên bố trên trang web của mình, khái niệm cốt lõi của nó là “điểm cuối trên chuỗi có thể định cấu hình ứng dụng người dùng chạy ULN (UltraLightNode)”. Các thành phần trên chuỗi của LayerZero dựa vào hai bên ngoài chuỗi bên ngoài để chuyển tiếp thông báo giữa các chuỗi — Oracle và Người chuyển tiếp.

Bất cứ khi nào bất kỳ tin nhắn M nào được gửi từ chuỗi A đến chuỗi B, hai hành động sau đây sẽ diễn ra:

  • đầu tiên, Oracle đợi cho đến khi giao dịch gửi thông báo M trên chuỗi A được hoàn tất và sau đó ghi vào chuỗi B cam kết cho gói thông báo, ví dụ: hàm băm của tiêu đề khối (định dạng chính xác có thể khác nhau giữa các chuỗi/nhà tiên tri khác nhau) tại chuỗi A chứa thông điệp đó M
  • sau đó Người chuyển tiếp gửi đến chuỗi B một "bằng chứng" (ví dụ: Bằng chứng Merkle) rằng tiêu đề được lưu trữ chứa thông báo M

LayerZero tuyên bố rằng “Thiết kế của LayerZero loại bỏ khả năng thông đồng”. Nhưng trên thực tế, tuyên bố đó không đúng (điều mà chúng tôi chứng minh trong thử nghiệm được trình bày bên dưới), vì mỗi ứng dụng người dùng có thể xác định Relayer và Oracle của riêng mình. LayerZero không đảm bảo theo thiết kế rằng các thành phần đó là độc lập và chúng không thể thông đồng với nhau. Tùy thuộc vào ứng dụng người dùng để cung cấp những đảm bảo đó. Và nếu ứng dụng chọn phá vỡ chúng, thì không có gì trong cơ chế LayerZero có thể ngăn nó làm như vậy.

Hơn nữa, theo mặc định, tất cả các ứng dụng người dùng có thể thay đổi Relayer và Oracle bất kỳ lúc nào, xác định lại hoàn toàn các giả định bảo mật. Vì vậy, việc kiểm tra tính bảo mật của ứng dụng nhất định một lần là không đủ vì nó có thể đã thay đổi bất cứ lúc nào sau khi kiểm tra, như chúng tôi sẽ trình bày trong thử nghiệm của mình.

Cuộc thí nghiệm

Trong thử nghiệm của mình, chúng tôi đã quyết định tạo một mã thông báo đa chuỗi đơn giản, CarpetMoon, hoạt động trên cả Ethereum và Optimism, sử dụng ZeroLayer để giao tiếp giữa cả hai chuỗi.

Mã thông báo của chúng tôi ban đầu sử dụng mô hình bảo mật mặc định do LayerZero cung cấp, do đó, nó trông khá giống với hầu hết (nếu không phải tất cả) các ứng dụng LayerZero hiện đang triển khai. Do đó, nó thường an toàn như bất kỳ mã thông báo nào khác sử dụng LayerZero.

Đầu tiên, chúng tôi triển khai các hợp đồng mã thông báo của mình trên Ethereum và trên Optimism:
https://ethtx.info/mainnet/0xf4d1cdabb6927c363bb30e7e65febad8b9c0f6f76f1984cd74c7f364e3ab7ca9/
https://optimistic.etherscan.io/tx/0xf41389d71fa3942de5225efb067072728c6c6de56c241574187781db7c73d221

Và chúng tôi đã thiết lập định tuyến để LayerZero biết hợp đồng nào tương ứng với hợp đồng nào trên cả hai chuỗi:
https://ethtx.info/mainnet/0x19d78abb03179969d6404a7bd503148b4ac14d711f503752495339c96a7776e9/
https://optimistic.etherscan.io/tx/0x037b1bad33faa5607bb5835460a1d5caaf3a147dc3a09762ac7703befcdb3c3c

Vậy là mã thông báo đã được thiết lập, nó trông giống hệt như tất cả các mã thông báo đa chuỗi khác sử dụng LayerZero, với cấu hình mặc định, không có gì đáng ngờ.

Chúng tôi cung cấp cho người dùng thử nghiệm của mình, hãy gọi cô ấy là Alice, với mã thông báo thử nghiệm, vì vậy Alice có 1 tỷ mã thông báo ThảmMoon trên Ethereum:
https://ethtx.info/mainnet/0x7e2faa8426dacae92830efbf356ca2da760833eca28e652ff9261fc03042b313/

Giờ đây, Alice kết nối các mã thông báo đó với Chủ nghĩa lạc quan bằng cách sử dụng LayerZero.

Chúng tôi khóa mã thông báo trong tài khoản ký quỹ trên Ethereum:
https://ethtx.info/mainnet/0xe4dc3757b86bfda8e7baddc088fb1a599e083ed77034c29e5dd8bd11f1e17771/

Thông báo với giao dịch đang được gửi tới Optimism thông qua LayerZero:
https://layerzeroscan.com/101/address/0xc6005ccc1de4b300d538903b74848bff881d5dc5/message/111/address/0x201fe0d843b546f2e24d4c8444318d1c71b7d10d/nonce/1

Và các mã thông báo cầu nối đang được đúc trên Optimism, Alice hiện có 1 tỷ mã thông báo MoonCarpet trên Optimism:
https://optimistic.etherscan.io/tx/0x5388ced88cf562acafff82d6798f791b0b38b90ee106df9bf91c0d86306ec302

Ok, vậy là mọi thứ hoạt động như mong đợi, Alice bắc cầu cho các mã thông báo của cô ấy và thấy rằng có 1 tỷ mã thông báo MoonCarpet trong tài khoản ký quỹ trên Ethereum và 1 tỷ mã thông báo MoonCarpet trên tài khoản của cô ấy tại Optimism. Nhưng để đảm bảo rằng mọi thứ hoạt động chính xác, cô ấy chuyển lại một nửa số mã thông báo (500M MoonCarpet) trở lại Ethereum.

Vì vậy, chúng tôi bắt đầu với giao dịch đốt 500 triệu mã thông báo trên Optimism:
https://optimistic.etherscan.io/tx/0x118a57106488ad0bae1f3b920b1fd98b187752ad966f3a901fc53cff47f2097f

Thông tin về giao dịch đó được chuyển đến Ethereum:
https://layerzeroscan.com/111/address/0x201fe0d843b546f2e24d4c8444318d1c71b7d10d/message/101/address/0xc6005ccc1de4b300d538903b74848bff881d5dc5/nonce/1

Và đúng như dự đoán, 500 triệu mã thông báo MoonCarpet sẽ được gửi lại địa chỉ của Alice từ tài khoản ký quỹ:
https://etherscan.io/tx/0x27702e07a65a9c6a7d1917222799ddb13bb3d05159d33bbeff2ca1ed414f6a18

Cho đến bây giờ, mọi thứ hoạt động tốt, chính xác như giả định. Alice đã kiểm tra rằng cô ấy có thể chuyển mã thông báo từ Ethereum sang Optimism và ngược lại, cô ấy không có lý do gì phải lo lắng về mã thông báo MoonCarpet của mình.

Nhưng giả sử có điều gì đó không ổn — ví dụ: nhóm đằng sau mã thông báo của chúng tôi bị xâm phạm và kẻ xấu Bob có quyền truy cập vào cấu hình LayerZero cho ứng dụng của chúng tôi.

Với quyền truy cập như vậy, Bob có thể thay đổi Oracle và Relayer từ mặc định thành những cái do anh ta kiểm soát.

Xin lưu ý rằng đây là một cơ chế được cung cấp cho mọi ứng dụng sử dụng LayerZero, ăn sâu vào kiến ​​trúc của LayerZero, đây không phải là bất kỳ loại cửa hậu nào mà là một cơ chế tiêu chuẩn.

Vì vậy, Bob thay đổi Oracle thành EOA dưới sự kiểm soát của mình:
https://ethtx.info/mainnet/0x4dc84726da6ca7d750eef3d33710b5f63bf73cbe03746f88dd8375c3f4672f2f/

Và làm tương tự với Relayer:
https://ethtx.info/mainnet/0xc1d7ba5032af2817e95ee943018393622bf54eb87e6ff414136f5f7c48c6d19a/

Và bây giờ những điều kỳ lạ xảy ra. Với việc Oracle và Relayer hiện nằm dưới sự kiểm soát hoàn toàn của Bob, anh ta có thể đánh cắp mã thông báo của Alice. Mặc dù không có hành động nào xảy ra trên Optimism (token MoonCarpet vẫn nằm trong ví của Alice ở đó) Bob vẫn có thể thuyết phục hợp đồng thông minh MoonCarpet trên Ethereum (sử dụng cơ chế LayerZero) rằng anh ta đã đốt token ở chuỗi khác và anh ta có thể rút token MoonCarpet trên Ethereum.

Đầu tiên, anh ấy cập nhật blockhash tại Ethereum bằng cách sử dụng Oracle lừa đảo:
https://ethtx.info/0xde2edee2cc7f070120e96c9df90d86696970befcfc221e18c6ac4168bb5b1d92/

Và bây giờ anh ta có thể rút các mã thông báo còn lại từ ký quỹ:
https://ethtx.info/0xda695f374b375d5372efeca37aae4c5a17f114d5a76db1e86edebb0924bcdcc7/

Kết quả

Alice thậm chí sẽ không biết tại sao và khi nào điều gì đó không ổn đã xảy ra. Đột nhiên, mã thông báo MoonCarpet của cô ấy tại Optimism không còn được hỗ trợ bởi mã thông báo trên Ethereum.

Các hợp đồng thông minh không thể nâng cấp và đang hoạt động như dự định. Hoạt động đáng ngờ duy nhất là sự thay đổi của Oracle và Relayer, nhưng đây là một cơ chế thông thường được tích hợp sẵn trong LayerZero, vì vậy Alice thậm chí không thể biết liệu sự thay đổi này có chủ ý hay không. Và ngay cả khi Alice biết về sự thay đổi đó thì cũng đã quá muộn — kẻ tấn công có thể rút tiền trước khi cô kịp phản ứng.

Và LayerZero cũng không thể giúp gì ở đây — đây đều là những cơ chế thực thi hợp lệ của họ và họ không thể kiểm soát được nữa. Về mặt lý thuyết, bản thân ứng dụng có thể tự ngăn chặn việc thay đổi Oracle và Relayer, nhưng theo như chúng tôi biết thì không có ứng dụng nào đã được triển khai làm được điều đó.

Chúng tôi đã thực hiện thí nghiệm này để kiểm tra xem có ai để ý không, nhưng đúng như chúng tôi dự đoán, không ai để ý. Thực tế là không thể giám sát hiệu quả tất cả các ứng dụng được xây dựng bằng LayerZero để kiểm tra xem chính sách bảo mật của chúng có thay đổi hay không và để cảnh báo người dùng nếu điều đó xảy ra.

Ngay cả khi một người có thể nắm bắt được rằng Oracle và Relayer đã thay đổi theo cách gây ra rủi ro bảo mật, thì khi điều đó xảy ra thì đã quá muộn. Vì Oracle và Relayer mới hiện có thể tự do chọn kiểm duyệt hoặc đơn giản là vô hiệu hóa giao tiếp giữa các chuỗi, người dùng thường không thể làm bất cứ điều gì về điều đó. Điều này được thể hiện rõ ràng trong thử nghiệm của chúng tôi, vì ngay cả khi Alice nhận thấy sự thay đổi trong cấu hình ứng dụng, cô ấy cũng không thể làm được gì nhiều với mã thông báo bắc cầu của mình — Oracle và Người chuyển tiếp mới không còn lắng nghe trên chuỗi ban đầu nên họ không chuyển tiếp tín hiệu tin nhắn trở lại Ethereum.

Kết luận và CTA

Như chúng ta có thể thấy ở trên, mặc dù mã thông báo của chúng tôi được tạo bằng LayerZero và sử dụng cơ chế của nó như dự định, nhưng chúng tôi vẫn có thể đánh cắp tiền từ ký quỹ của mã thông báo. Tất nhiên, đó là lỗi của ứng dụng (mã thông báo CarpetMoon trong trường hợp của chúng tôi) chứ không phải do chính LayerZero, nhưng điều đó chứng tỏ rằng bản thân LayerZero không cung cấp bất kỳ đảm bảo bảo mật nào .

Khi LayerZero mô tả mô hình bảo mật của họ liên quan đến Oracle và Relayer, họ cho rằng chủ sở hữu ứng dụng (hoặc ai đó sở hữu khóa riêng tư của họ) sẽ không làm bất cứ điều gì phi lý. Nhưng giả định đó là không chính xác trong một môi trường đối nghịch. Hơn nữa, nó yêu cầu người dùng tin tưởng chủ sở hữu ứng dụng với tư cách là bên thứ ba đáng tin cậy.

Trên thực tế, do điều này, người ta không thể đưa ra bất kỳ giả định nào về tính bảo mật của các ứng dụng được xây dựng bằng LayerZero — mỗi ứng dụng nên được coi là rủi ro cho đến khi được chứng minh ngược lại.

Trên thực tế, toàn bộ câu chuyện bắt đầu với chúng tôi bằng một PR mà chúng tôi dự định đưa tất cả các mã thông báo đa chuỗi vào trang web L2BEAT — chúng tôi gặp khó khăn trong việc tìm ra cách đánh giá rủi ro của chúng. Trong khi phân tích các vectơ rủi ro, chúng tôi đã nảy ra ý tưởng cho thử nghiệm của mình.

Đối với L2BEAT, hậu quả là chúng tôi phải đặt cảnh báo lên trên mọi ứng dụng được xây dựng bằng LayerZero, cảnh báo về các rủi ro bảo mật có thể xảy ra. Nhưng chúng tôi muốn mở một cuộc thảo luận rộng hơn về các mô hình bảo mật, vì chúng tôi tin rằng bảo mật biệt lập là một phản mẫu nên tránh, đặc biệt là trong không gian của chúng tôi.

Chúng tôi tin tưởng rằng khi các mô hình bảo mật biệt lập như trong LayerZero ngày càng trở nên phổ biến, thì sẽ ngày càng có nhiều dự án lạm dụng chúng, gây ra nhiều thiệt hại và làm tăng sự không chắc chắn cho toàn ngành.