Bỏ qua đến nội dung chính
Về trang chủ
Tech tools-cli 6 phút đọc

Đừng Nhầm Lẫn! 🤯 Vì Sao So Sánh Số Lượng CVE Về An Toàn Bộ Nhớ Giữa Rust Và C/C++ Là Sai Lầm Lớn?

Việc so sánh trực tiếp số lượng CVE về an toàn bộ nhớ giữa Rust và C/C++ là không chính xác, bởi Rust có tiêu chí nghiêm ngặt hơn nhiều khi coi cả những 'lỗ hổng tính đúng đắn' trong thư viện an toàn là một CVE, trong khi C/C++ xem đây là lỗi người dùng.

Tier 2 · nguồn 99% độ tin cậy Auto-priority
Nguồn gốc kobzol.github.io

Chào mừng quý độc giả của Kalera News! Với tư cách là Sylvie, tổng biên tập, tôi muốn chia sẻ một góc nhìn quan trọng về cách chúng ta đánh giá mức độ an toàn của các ngôn ngữ lập trình, đặc biệt là Rust và C/C++. Một bài viết thú vị từ kobzol.github.io đã làm rõ một sự thật gây hiểu lầm: việc so sánh trực tiếp số lượng CVE (Common Vulnerabilities and Exposures) giữa Rust và C/C++ là hoàn toàn sai lệch. Hãy cùng tìm hiểu tại sao! 👇

Tóm tắt: Sự Khác Biệt Trong CVE Về An Toàn Bộ Nhớ Giữa Rust Và C/C++

So sánh số liệu CVE thô giữa Rust và C/C++ có thể dẫn đến những kết luận sai lầm nghiêm trọng. Trong C/C++, một lỗi an toàn bộ nhớ do việc truyền đối số không hợp lệ vào thư viện thường được coi là "lỗi người dùng" (lạm dụng API) và không được cấp CVE. Ngược lại, trong Rust, nếu bất kỳ API "an toàn" nào có thể gây ra lỗi an toàn bộ nhớ trong bất kỳ trường hợp nào, nó sẽ bị coi là một lỗ hổng tính đúng đắn (soundness hole) trong thư viện và được cấp CVE. Điều này có nghĩa là tiêu chí cấp CVE của Rust nghiêm ngặt hơn đáng kể so với C/C++. 🧐

---

Mô hình C/C++: "Lạm Dụng API" Là Lỗi Của Người Dùng

Trong C và C++, các thư viện nói chung không chịu trách nhiệm về các lỗi an toàn bộ nhớ do người dùng sử dụng không đúng cách.

Ví dụ điển hình: `curl`

Ngay cả trong các thư viện C mạnh mẽ, được bảo trì tốt như curl, những đầu vào đơn giản cũng có thể gây ra Undefined Behavior (UB – hành vi không xác định) và lỗi phân đoạn (segmentation faults).

c #include <curl/curl.h> int main ( void ) { curl_getenv ( NULL ); }

Kết quả: bash $ gcc test.c -otest -lcurl -Wall -Wextra $ ./test Segmentation fault (core dumped)

Tại sao đây KHÔNG được phân loại là CVE trong `curl`:

1. Hệ thống kiểu dữ liệu hạn chế: Trong C, việc chỉ định chính xác các hợp đồng API (bất biến, điều kiện tiên quyết, v.v.) thường là bất khả thi. Các tác giả thư viện khó có thể tài liệu hóa hoặc bảo vệ chống lại mọi hình thức sử dụng không đúng cách. 2. Số lượng vấn đề tiềm tàng khổng lồ: Vì việc gây ra UB trong C/C++ cực kỳ dễ dàng, việc gắn cờ mọi hành vi lạm dụng tiềm tàng là một CVE của thư viện sẽ làm tràn ngập hệ sinh thái với hàng triệu báo cáo.

> "Trong C và C++, chúng ta thường không coi những tình huống tương tự là đủ điều kiện để nhận một CVE trong thư viện được sử dụng. Nói cách khác, chúng ta tạo CVE cho những cách sử dụng sai cụ thể của một thư viện, chứ không phải cho sự tồn tại của một API thư viện có thể bị lạm dụng." 💬

---

Mô hình Rust: Lỗ Hổng Tính Đúng Đắn (Soundness Holes)

Trong Rust, ranh giới giữa mã an toàn (safe) và không an toàn (unsafe) chuyển toàn bộ trách nhiệm an toàn bộ nhớ sang tác giả thư viện. 🧑‍💻

Ví dụ điển hình: `hyper` (Giả định)

Nếu một nhà phát triển viết một chương trình Rust "an toàn" bằng cách sử dụng một thư viện như hyper và truyền một đối số không hợp lệ:

rust fn main () { hyper::foo ( None ); }

Nếu chương trình này bị lỗi phân đoạn, nó ngay lập tức được phân loại là một CVE trong hyper.

Tại sao đây LẠI được phân loại là CVE trong Rust:

* Cam kết của Rust an toàn: Nếu người dùng không sử dụng từ khóa unsafe, thì việc họ kích hoạt lỗi an toàn bộ nhớ là không thể về mặt toán học. * Lỗ hổng tính đúng đắn: Nếu một API thư viện có thể được sử dụng bằng bất kỳ cách nào để gây ra lỗi bộ nhớ mà người dùng không cần viết unsafe, thì API đó được coi là không có tính đúng đắn (unsound). Đây là một lỗ hổng nghiêm trọng. * Báo cáo chủ động: Các CVE của Rust thường được ban hành cho tiềm năng gây ra lỗi bộ nhớ, ngay cả khi chưa có khai thác thực tế hoặc chương trình lỗi nào được quan sát trong thực tế. ✨

> "Trong Rust, khi có bất kỳ cách nào có thể sử dụng một thư viện để gây ra lỗi bộ nhớ mà không cần dùng từ khóa unsafe trong mã người dùng, thì đó luôn là lỗi của thư viện, chứ không phải của mã người dùng." 🛡️

---

An Toàn Bộ Nhớ Trong Rust Theo Quy Mô

Hợp đồng về an toàn bộ nhớ trong Rust được đơn giản hóa thành một quy tắc nhị phân:

* API an toàn (Không có từ khóa unsafe): Người dùng được đảm bảo an toàn bộ nhớ 100%. Mọi lỗi bộ nhớ là vấn đề của thư viện hoặc trình biên dịch. * API không an toàn (Yêu cầu từ khóa unsafe): Người dùng phải tự xác minh các bất biến. Trách nhiệm quay trở lại mức độ như trong C/C++.

Bởi vì mã Rust an toàn không thể "sử dụng sai thư viện" và gây ra UB, các lỗi an toàn bộ nhớ được cô lập và khắc phục bên trong chính các thư viện, tự động bảo mật tất cả người dùng phụ thuộc khi họ cập nhật. Điều này tạo ra một hệ sinh thái mạnh mẽ hơn rất nhiều. 💪

---

Kết Luận

So sánh số lượng CVE thô để đánh giá mức độ an toàn tương đối của Rust và C/C++ là một sự so sánh khập khiễng. Các tiêu chuẩn cao của Rust phân loại các lỗ hổng API tiềm tàng (lỗ hổng tính đúng đắn) là CVE, trong khi C/C++ chỉ ghi nhận CVE cho các lỗ hổng đã được khai thác hoặc lỗi nội bộ cụ thể của thư viện, bỏ qua vô số cách người dùng có thể biên dịch an toàn nhưng thực thi không an toàn các lời gọi thư viện C/C++. Hy vọng bài viết này đã giúp quý vị độc giả của Kalera News hiểu rõ hơn về sự khác biệt quan trọng này và có cái nhìn khách quan hơn khi đánh giá các ngôn ngữ lập trình! Hẹn gặp lại trong những bài viết tiếp theo! 👋