TLA+ công cụ tránh lỗi Reentrancy trong smart contract của ICP

Chúng ta đang sống trong thời đại của tiền điện tử và hợp đồng thông minh, khi mà blockchain và các ứng dụng phi tập trung đang trở thành một phần quan trọng của cuộc sống kỹ thuật số của chúng ta. Tuy nhiên, điều này cũng đi kèm với những thách thức, chẳng hạn như các lỗ hổng bảo mật trong các hợp đồng thông minh có thể gây ra những thiệt hại tài chính lớn. Trong các công cụ lập trình của Internet Computer, có một công cụ giúp giải quyết vấn đề này: TLA+.

Vấn đề hiện tại: Tấn công Reentrancy

Tấn công Reentrancy là một trong các loại tấn công mà hacker thường xuyên sử dụng khi phát hiện ra lỗ hổng Reentrancy.

Vào tháng 6 năm 2016, sự phấn khích đang cao cấp. “The DAO,” được xây dựng trên blockchain Ethereum, sắp trở thành quỹ đầu tư hoàn toàn kỹ thuật số và phi tập trung đầu tiên trên thế giới. Nhưng chỉ trong vài tuần, nó đã trở thành biểu tượng của các vụ tấn công DeFi thay vì điều đó, sau khi một kẻ tấn công đã rút 50 triệu đô la giá trị Ether ra khỏi nó.

Để tấn công The DAO, kẻ tấn công đã lợi dụng một lỗi gọi là lỗi “reentrancy,” một loại lỗi song song mà một phương thức của hợp đồng thông minh cụ thể được gọi khi một phương thức khác đang thực thi. Và The DAO chỉ là vụ hack đầu tiên trong một chuỗi các vụ hack của các hợp đồng thông minh đối với các lỗi tương tự. Những hợp đồng sau này bao gồm Uniswap/Lendf.Me với 25 triệu đô la bị đánh cắp vào năm 2020, CREAM bị rút sạch 18 triệu đô la vào năm 2021 và Fei mất 80 triệu đô la vào năm 2022. Lý do tại sao những lỗi này vẫn tồn tại là vì chúng có thể liên quan đến sự tương tác không mong đợi của mã nguồn phân tán trong một hợp đồng thông minh, hoặc đôi khi thậm chí là trong các hợp đồng thông minh khác nhau hoàn toàn. Số lượng tương tác mã nguồn như vậy có thể rất lớn và khó phát hiện và loại bỏ những tương tác không mong muốn.

Khái niệm: TLA+ là gì?

TLA+ (viết tắt của “Temporal Logic of Actions”: ngôn ngữ logic hành động tạm thời) là một ngôn ngữ được sử dụng để xác minh các hệ thống phức tạp, nó có thể tìm ra lỗi bảo mật trong hợp đồng thông minh của Internet Computer.

TLA+ đi kèm với một bộ công cụ cho việc xác minh hình thức nhẹ về cơ bản thông qua kiểm tra mô hình. Thông qua việc kiểm tra mô hình, nó khám phá mọi tương tác đồng thời có thể có của một mô hình của mã nguồn – chính là lĩnh vực khó kiểm tra nhất – và tìm ra lỗi. Hãy tưởng tượng một người diệt côn trùng chiếu sáng vào từng góc khuất để phơi bày và loại bỏ các côn trùng không mong muốn ẩn giấu trong những góc tối thường bị bỏ lỡ hoặc bị bỏ qua. Quan trọng hơn, sau khi xây dựng mô hình của mã nguồn, kiểm tra mô hình chạy gần như không cần sự can thiệp của con người nữa, làm cho nó rất hiệu quả về chi phí. Để minh họa với một số con số tưởng tượng: nếu các phương pháp tiêu chuẩn trong ngành (như kiểm tra và đánh giá bảo mật) loại bỏ 80% lỗi, và việc xác minh hình thức “nặng ký” loại bỏ 99%, với TLA+ bạn có thể loại bỏ 90% lỗi với một phần nhỏ công sức so với xác minh “nặng ký”.

Công Dụng Của TLA+

Công dụng chính của TLA+ nằm ở việc kiểm tra và xác minh các hệ thống phức tạp. Nó có khả năng loại bỏ lỗi và xác minh sự đúng đắn của các hệ thống. TLA+ được sử dụng để kiểm tra các khía cạnh quan trọng của Internet Computer, bao gồm các hợp đồng thông minh quan trọng liên quan đến bảo mật. Một ví dụ cụ thể là sự kiểm tra của TLA+ trên các hợp đồng thông minh Chain-Key Bitcoin (ckBTC) canisters, mà chúng tôi sẽ chia sẻ dưới đây.

Cách Sử Dụng TLA+

Trước khi TLA+ có thể phát hiện bất kỳ lỗi nào, chúng ta phải cung cấp cho nó hai thứ:

  1. Tạo mô hình của hệ thống của chúng ta bằng ngôn ngữ TLA+.
  2. Xác định thuộc tính TLA+ mà chúng ta mong muốn hệ thống đạt được.

Mô hình là một phiên bản đơn giản hóa, nhưng vẫn được xác định đầy đủ của hệ thống. Trong trường hợp của chúng tôi, nó bao gồm hợp đồng thông minh ckBTC mà chúng ta đang kiểm tra, cũng như tất cả các phần khác liên quan, chẳng hạn như hợp đồng sổ cái và mạng Bitcoin. Đối với mỗi thành phần, chúng tôi mô hình hóa trạng thái của nó, cũng như cách các hành động liên quan đến người dùng cuối có thể thực hiện (chẳng hạn như chuyển BTC hoặc ckBTC, gửi BTC hoặc gọi các hoạt động khác mà ckBTC mở ra) thay đổi trạng thái. Tất cả các yếu tố này đều được đơn giản hóa một phần trong mô hình; những phần mà phân tích tập trung (chẳng hạn như mã mình) được mô hình hóa cặn kẽ hơn và các phần khác (như mạng Bitcoin) thì ít chi tiết hơn. Trên thực tế, mô hình TLA+ tương tự như một bản thiết kế chi tiết của hệ thống.

Trực giác, thuộc tính chính mà chúng ta muốn đạt được là đảm bảo rằng ckBTC của chúng ta được hỗ trợ hoàn toàn. Nói cách khác, không người dùng nào nên có khả năng “double spend” (chi tiêu gấp đôi) số tiền BTC gửi của họ để nhận nhiều ckBTC hơn so với số BTC họ đã gửi. Nhưng để phân tích một thuộc tính như vậy, chúng ta phải làm cho trực giác này trở nên cụ thể bằng cách thể hiện nó một cách hình thức trong ngôn ngữ TLA+. Định nghĩa hình thức của chúng tôi nói rằng tổng cung cấp của ckBTC (tức là tổng số dư ckBTC của tất cả người dùng cuối, như được lưu trữ bởi sổ cái ckBTC) không vượt quá tổng số tiền BTC mà hợp đồng mình kiểm soát (tức là tổng số giá trị của tất cả các UTXO thuộc sở hữu của một địa chỉ gửi cụ thể).

Phát hiện và Khắc phục sự cố

Sau khi chúng ta đã tạo mô hình và thuộc tính, bộ công cụ TLA+ có thể phân tích mô hình. Để chạy phân tích, trước hết chúng ta xác định các thiết lập trong đó phân tích chạy. Ví dụ, thiết lập cho ckBTC của chúng ta bao gồm chỉ hai người dùng cuối khác nhau và một tổng cung cấp tiền bitcoin nhỏ (ví dụ: 5 Satoshi). Mặc dù thiết lập này rất hạn chế, các nghiên cứu thực tế cho thấy rằng hầu hết vấn đề trong các hệ thống máy tính có thể được tìm thấy với một số lượng thực thể nhỏ. Thiết lập nhỏ cho phép phân tích khám phá toàn bộ các trình tự hành động có thể có trong mô hình, và kiểm tra rằng các thuộc tính đã được nêu bên trên đều đúng trong bất kỳ trình tự nào. Hơn nữa, phân tích chạy hoàn toàn tự động, tức là không cần sự can thiệp của con người. Nếu các thuộc tính không đúng, nó sẽ cung cấp cho chúng ta trình tự chính xác các hành động đã vi phạm thuộc tính.

Ví dụ, phân tích có thể phát hiện rằng chúng ta có thể vi phạm thuộc tính “không có ckBTC không được hỗ trợ” trong tình huống như được minh họa trong hình sau:

  • Người dùng cuối gửi BTC, giống như trước đây
  • Tuy nhiên, lần này, người dùng cuối kế tiếp yêu cầu hợp đồng thông minh ckBTC cập nhật số dư hai lần trong thời gian ngắn liên tiếp. Trên Internet Computer, những cập nhật này có thể tương tác đồng thời với các hợp đồng thông minh khác.
  • Cả hai cập nhật đang chạy đồng thời yêu cầu mạng Bitcoin tìm kiếm tất cả các UTXO được gửi bởi người dùng cuối và cả hai đều nhận được cùng một UTXO được gửi trong bước 1 trong phản hồi; vì UTXO này chưa có trong danh sách “đã xử lý”, cả hai cập nhật đều cho rằng UTXO này là mới.
  • Cả hai cập nhật yêu cầu sổ cái ckBTC đúc ckBTC tương ứng cho tất cả các UTXO mới theo tỷ lệ 1:1, và sau khi hoàn thành điều này, chúng thêm UTXO mới được tìm thấy vào danh sách các UTXO đã xử lý. Do đó, ở cuối bước 4, chúng ta còn lại trong trạng thái trong đó cung cấp ckBTC là gấp đôi tổng số tiền UTXO trong các địa chỉ gửi, vi phạm thuộc tính “không có ckBTC không được hỗ trợ”. Lưu ý rằng lỗi này chỉ xảy ra vì việc thực hiện cập nhật song song của số dư người dùng cuối – thực tế là cùng một loại lỗi tái nhập, cùng loại lỗi đã đánh đổ The DAO.

Một cách để khắc phục vấn đề này là ngăn cập nhật số dư chạy song song cho cùng một người dùng cuối. Chúng ta có thể làm điều này bằng cách khiến hợp đồng thông minh lưu trữ người dùng cuối trong một danh sách các người dùng “bị khóa” khi một cập nhật số dư bắt đầu và duy trì họ trong danh sách này trong thời gian cập nhật. Nếu người dùng cuối cố gắng khởi tạo một cập nhật số dư song song khác, cập nhật sẽ kiểm tra và tìm thấy người dùng cuối cụ thể này trên danh sách người dùng “bị khóa” và kết thúc.

Lưu ý rằng chúng tôi đã đơn giản hóa cuộc tấn công ở đây một chút: việc khóa thực sự là một mô hình phổ biến đối với các hợp đồng thông minh IC, và hợp đồng thông minh ckBTC đã triển khai nó từ đầu. Tuy nhiên, việc khóa đã được thực hiện không đúng cách, mở cửa cho cuộc tấn công ở trên. TLA+ đã có thể phát hiện điều này. Ngoài ra, chúng tôi cũng đã tìm thấy một số trường hợp cạnh nhau khác vi phạm thuộc tính “không có ckBTC không được hỗ trợ” và các thuộc tính quan trọng khác. Sau khi áp dụng tất cả các sửa đổi, TLA+ đã xác minh và xác nhận rằng không còn vi phạm thuộc tính nào trong thiết lập đã xác định của chúng tôi.

Nên Sử Dụng TLA+ Cho Hợp Đồng Thông Minh Của Bạn Không?

Tất nhiên! OK, OK, có lẽ tôi nên cung cấp một câu trả lời tinh vi hơn. Nhóm Nghiên cứu và Phát triển của chúng tôi sử dụng nó cho các hợp đồng thông minh quan trọng trên Internet Computer mỗi khi lỗi đồng thời. Ví dụ, phân tích TLA+ đã phát hiện ra những lỗi đồng thời tinh tế trong các hợp đồng thông minh quản lý và sổ cái của Internet Computer mà đã bị bỏ lỡ trong các đánh giá bảo mật thủ công và có thể đã gây ra vấn đề lớn. Dấu chấm và gạch dưới – TLA+ chắc chắn tỏa sáng trong việc tìm ra các vấn đề phức tạp như vậy.

Tất nhiên, có một khoản phí phải trả về việc học cách sử dụng nó và sau đó xây dựng các mô hình. Nhưng dựa trên kinh nghiệm, giá trị này là hợp lý, đặc biệt khi xem xét tính toán trong lĩnh vực bảo mật blockchain. Và người ta không nên bị làm sợ bởi ngôn ngữ TLA+ chính nó. Mặc dù có tên đáng sợ, nó khá đơn giản để tiếp cận các khả năng mạnh mẽ của nó. Trong thực tế, một tờ hướng dẫn TLA+ mô tả gần như tất cả các tính năng của TLA+ về cơ bản có thể được thể hiện trên một trang giấy.

Điều quan trọng hơn, công sức cần thiết để xây dựng một mô hình tương tự như việc đánh giá bảo mật thủ công tiêu chuẩn. Ví dụ, để hợp đồng thông minh minter của ckBTC, hiểu thiết kế và tạo mô hình ban đầu và các thuộc tính đã khiến 1 người mất khoảng 3 tuần tổng cộng. Mô hình TLA+ kết quả là ngắn gọn hơn rất nhiều so với mã nguồn thực hiện, cả về mặt đơn giản hóa so với mã nguồn và về mặt trừu tượng của TLA+. Mô hình của minter ckBTC có khoảng ~250 dòng mã, so với hàng ngàn dòng mã Rust thực hiện. Có lẽ bất ngờ, một trong những phần khó khăn nhất, về mặt công sức, là việc xác định các thuộc tính mong muốn, vì thường có sự không thống nhất trong việc định rõ các thuộc tính trực giác. Sau khi mô hình hoàn thành, phân tích (kiểm tra mô hình) diễn ra tự động. Phân tích có thể chạy trong thời gian dài – ví dụ, đối với ckBTC, nó mất hơn 20 giờ để hoàn thành. Cuối cùng, một lợi ích bổ sung của TLA+ là việc mô hình hóa và phân tích có thể thực hiện ở giai đoạn thiết kế, trước khi mã nguồn thực hiện thậm chí còn chưa được thực hiện. Điều này có thể giúp loại bỏ việc phải tiến hành việc sửa đổi lớn do lỗi thiết kế sau này.

Điểm hạn chế, trường hợp mà TLA+ không có ích

Mặt tiêu cực, TLA+ ít hữu ích cho các chương trình tuần tự phức tạp, so với các chương trình song song. Nó cũng không tốt trong việc xử lý các giao thức mật mã phức tạp. Có các công cụ khác (như Scyther hoặc Tamarin) được phát triển chuyên để kiểm tra bảo mật giao thức. Tuy nhiên, TLA+ có thể được sử dụng để kiểm tra các khía cạnh không phải là bảo mật của giao thức mật mã.

Kết: TLA+ là một công cụ mạnh mẽ cho việc kiểm tra và xác minh các hệ thống phức tạp, và nó có tiềm năng lớn trong việc kiểm tra bảo mật và sự đúng đắn của các hợp đồng thông minh trên các nền tảng blockchain. Việc sử dụng TLA+ có thể giúp phát hiện và khắc phục các lỗi phức tạp trước khi chúng gây ra các vấn đề lớn, giúp cải thiện tính an toàn và tin cậy của các ứng dụng và hợp đồng thông minh blockchain. Tuy nhiên, việc sử dụng TLA+ đòi hỏi kiến thức về ngôn ngữ và một phần công sức để xây dựng mô hình và thiết lập thuộc tính, nhưng đối với các ứng dụng quan trọng và phức tạp, đây có thể là một đầu tư đáng giá.

Vietnam Pham – Click Digital

Leave a Reply

Your email address will not be published. Required fields are marked *