Internet đang gặp phải một vấn đề rất lớn với C/C++, khiến các nhà phát triển “toát mồ hôi”

Một lỗi ảnh hưởng đến iPhone, một lỗi khác ảnh hưởng đến Windows và lỗi thứ ba ảnh hưởng đến các máy chủ chạy Linux - cuộc tấn công tổng lực của một “đội quân hắc ám” nào đó chăng? Thoạt nhìn thì những lỗi này có vẻ không liên quan, nhưng thực tế cả ba đều có thể bắt nguồn từ nguyên nhân một phần mềm đang khai thác được viết bằng ngôn ngữ lập trình mà có thể gây ra một loại lỗi gọi là "memory unsafety". Do không thể ngăn chặn được các loại lỗi này, những ngôn ngữ lập trình như C và C++ đã vô tình tạo điều kiện cho một luồng lỗ hổng bảo mật máy tính nghiêm trọng lây lan và phát triển gần như không có hồi kết trong nhiều năm.

Hãy tưởng tượng bạn có một chương trình với danh sách 10 số. Điều gì sẽ xảy ra nếu bạn yêu cầu danh sách cho phần tử thứ 11 của nó? Hầu hết chúng ta đều nói rằng một lỗi nào đó sẽ xảy ra và trong ngôn ngữ lập trình an toàn cho bộ nhớ (ví dụ: Python hoặc Java) đều này là hoàn toàn chính xác. Trong một ngôn ngữ lập trình không an toàn cho bộ nhớ, nó sẽ xem xét bất cứ ngóc ngách nào trong bộ nhớ để tìm ra phần tử thứ 11 (nếu phần tử này có tồn tại) và cố gắng truy cập vào phần tử này. Đôi khi điều này sẽ dẫn đến sự cố, ngay cả khi phần bộ nhớ đó không liên quan gì đến danh sách của chúng ta. Loại lỗ hổng bảo mật này được gọi là lỗi tràn bộ đệm (buffer-overflow), và đây là một trong những loại lỗ hổng bảo mật liên quan đến bộ nhớ phổ biến nhất. HeartBleed cũng là một lỗ hổng buffer-overflow và đã tác động đến 17% các máy chủ web bảo mật trên internet. Cụ thể, HeartBleed cho phép đọc 60 kilobyte các danh sách, bao gồm cả mật khẩu và các dữ liệu khác của người dùng.

Lỗi tràn bộ đệm

Ngoài ra, cũng có các loại lỗ hổng bảo mật bộ nhớ khác liên quan đến C/C ++. Các ví dụ có thể kể đến là type confusion (trộn lẫn các loại giá trị tồn tại tại một vị trí trong bộ nhớ), use after free (sử dụng một phần bộ nhớ sau khi bạn đã hoàn tác các tác vụ cần thiết với hệ điều hành) và use of uninitialized memory (sử dụng một phần không gian bộ nhớ trước khi bạn lưu trữ bất cứ thứ gì trong đó). Cùng với nhau, chúng tạo thành một số lỗ hổng phổ biến nhất trên các phần mềm được sử dụng rộng rãi như Firefox, Chrome, Windows, Android và iOS. Các chuyên gia bảo mật đã theo dõi cũng như đưa ra những tư vấn bảo mật cho các nền tảng này trong nhiều năm, và họ nhận thấy rằng trong hầu hết bản phát hành cho các nền tảng này, hơn một nửa các lỗ hổng là có liên quan đến mất an toàn bộ nhớ. Đáng lo ngại hơn, các lỗ hổng nghiêm trọng trong số đó (nói chung là các lỗ hổng có thể dẫn đến việc thực thi mã từ xa, cho phép kẻ tấn công có thể chạy bất kỳ mã nào chúng muốn trên máy tính của bạn, đây thường là loại lỗ hổng nghiêm trọng nhất) hầu như luôn đe dọa trực tiếp đến sự an toàn của bộ nhớ. Trong năm 2018, Alex Gaynor - một kỹ sư bảo mật phần mềm tại Mozilla, đã thực hiện các nghiên cứu bảo mật đối với những thư viện xử lý hình ảnh nguồn mở được sử dụng rộng rãi như ImageMagick và GraphicsMagic, và kết quả là ông tìm thấy hơn 400 lỗ hổng bảo mật liên quan đến bộ nhớ.

Hacker

Nếu những lỗ hổng này trở nên phổ biến, chúng có thể gây ra nhiều thiệt hại trên diện rộng. Tại sao các ngôn ngữ lập trình này vẫn còn được sử dụng phổ biến dù chứa đựng những lỗ hổng nghiêm trọng như vậy? Nguyên nhân đầu tiên đó là tuy rằng hiện nay không thiếu các ngôn ngữ lập trình có thể ngăn ngừa các lỗ hổng gây mất an toàn cho bộ nhớ, nhưng C và C++ là những ngôn ngữ lập trình đã có tuổi đời lên đến hàng thập kỷ, được sử dụng rất phổ biến và gần như đã trở thành một “tôn giáo”, trong khi các ngôn ngữ có thể bảo đảm an toàn bộ nhớ có thể sử dụng cho lập trình cấp thấp như trình duyệt web và hệ điều hành, đơn cử như Rust và Swift… mới chỉ bắt đầu được biết đến nhiều hơn một chút.

Một vấn đề lớn hơn là khi các nhà phát triển ngồi xuống và bàn xem mình sẽ chọn ngôn ngữ lập trình nào cho dự án mới, họ thường đưa ra quyết định dựa trên ngôn ngữ mà nhóm của họ am hiểu nhất, cũng như hiệu suất và hệ sinh thái của các thư viện có thể được tận dụng. Bảo mật gần như không bao giờ được xem xét như một yếu tố cốt lõi. Điều này có nghĩa là các ngôn ngữ lập trình nhấn mạnh đến bảo mật thường không đáp ứng được các yếu tố còn lại, và đó là một bất lợi khiến chúng không được chọn.

Hơn nữa, nhiều dự án phần mềm quan trọng có liên quan đến bảo mật internet không phải là mới, chúng đã được bắt đầu xây dựng từ hơn một thập kỷ trước trở lên, ví dụ Linux, OpenSSL và máy chủ web Apache đều đã có tuổi đời hơn hai mươi năm. Đối với các dự án lớn như thế này, viết lại mọi thứ bằng một ngôn ngữ mới không phải là một điều đơn giản hay có thể được triển khai một sớm một chiều. Điều này có nghĩa là các dự án sẽ cần phải được viết bằng hai ngôn ngữ, thay vì một như truyền thống, và do đó, sự phức tạp cũng sẽ tăng lên đáng kể. Đồng thời cũng có nghĩa là sẽ cần phải đào tạo lại một đội ngũ lớn, dẫn đến tốn thời gian và tiền bạc hơn.

Cuối cùng, vấn đề lớn nhất là nhiều nhà phát triển không tin rằng bảo mật trong ngôn ngữ lập trình là một vấn đề lớn. Nhiều kỹ sư phần mềm tin rằng vấn đề không phải là các ngôn ngữ như C/C++ tạo điều kiện thuận lợi cho các lỗ hổng này được khai thác, mà là do các nhà phát triển khác đã viết mã lỗi. Theo lý thuyết này, vấn đề không phải là việc cố gắng lấy mục thứ 11 trong danh sách 10 mục có thể dẫn đến lỗ hổng nghiêm trọng, mà là ở chỗ ai đó đã viết mã cố gắng lấy mục thứ 11 ở vị trí đầu tiên, và họ là một kỹ sư hoặc là không đủ trình độ hoặc là không đủ kỷ luật đạo đức nghề nghiệp. Nói cách khác, một số người nghĩ rằng vấn đề không nằm ở chính ngôn ngữ lập trình, mà là do một số người không biết sử dụng các ngôn ngữ lập trình sao cho tốt.

buffer-overflow

Một trong những tiêu chí khi chọn ngôn ngữ lập trình đó là: "Sự lựa chọn này sẽ ảnh hưởng đến bảo mật như thế nào?"

Các lỗ hổng này có ở khắp mọi nơi và ảnh hưởng đến cả các công ty có ngân sách bảo mật lớn nhất và các nhà phát triển tài năng nhất! Và làm thế nào chúng ta có thể khiến cho các ngôn ngữ lập trình an toàn bộ nhớ trở nên phổ biến hơn, dễ học hơn. Sau hàng trăm, hàng ngàn lỗ hổng đáng ra có thể ngăn chặn được bằng cách sử dụng một ngôn ngữ lập trình tốt hơn, bằng chứng cho thấy rõ rằng "hãy cố gắng hơn để không gặp lỗi" không phải là một chiến lược khả thi.

Tuy nhiên, vẫn có một vài tin tốt. Không phải ai cũng phủ nhận về vấn đề này. Rust là một ngôn ngữ lập trình tương đối mới, nhắm tới mục đích sử dụng cho mọi vấn đề mà C và C++ gặp phải, trong khi vẫn đảm bảo an toàn cho bộ nhớ và do đó tránh được những cạm bẫy bảo mật kiểu này. Rust đang ngày càng được chấp nhận rộng rãi. Hiện tại, nó được sử dụng bởi Mozilla, Google, Dropbox và Facebook và điều này chứng tỏ một điều là nhiều doanh nghiệp, tổ chức cũng đang bắt đầu tìm kiếm các giải pháp mang tính hệ thống cho các vấn đề về mất an toàn bộ nhớ. Ngoài ra, Apple Swift cũng là một loại ngôn ngữ lập trình an toàn cho bộ nhớ, trong khi người tiền nhiệm của nó là Objective-C, thì hoàn toàn không.

HeartBleed

Có một số điều chúng ta có thể làm để thúc đẩy quá trình tìm kiếm các giải pháp toàn diện cho thảm họa bảo mật mất an toàn bộ nhớ đang ngày càng trở nên nghiêm trọng hơn. Đầu tiên, chúng ta nên có nhận thức tốt hơn trong việc định lượng mức độ thiệt hại mà sự mất an toàn bộ nhớ gây ra. Dự án CVE, một cơ sở dữ liệu toàn ngành về các lỗ hổng đã biết, có thể theo dõi mọi lỗ hổng cho dù đó có phải là vấn đề liên quan đến sự mất an toàn bộ nhớ hay không, và liệu ngôn ngữ lập trình an toàn bộ nhớ có ngăn chặn được các lỗ hổng không. Điều này sẽ giúp chúng ta trả lời được các câu hỏi như, "Các dự án nào sẽ được hưởng lợi ích khi sử dụng các ngôn ngữ lập trình an toàn cho bộ nhớ?".

Thứ hai, chúng ta nên đầu tư nhiều hơn vào việc nghiên cứu xem làm thế nào để di chuyển các dự án phần mềm lớn hiện có sang bộ nhớ ngôn ngữ an toàn một cách tối ưu nhất. Hiện tại, ý tưởng di chuyển một cái gì đó như nhân Linux sang một ngôn ngữ lập trình khác là một nhiệm vụ gần như bất khả thi. Do đó, các nghiên cứu chuyên dụng về loại công cụ nào có thể tạo điều kiện thuận lợi cho quá trình chuyển đổi này hoặc cách ngôn ngữ lập trình có thể được thiết kế để trở nên đơn giản hơn sẽ giúp giảm đáng kể chi phí, công sức và thời gian trong việc cải thiện các dự án cũ và có quy mô lớn.

Cuối cùng, chúng ta có thể thay đổi suy nghĩ của mọi người xung quanh vấn đề bảo mật trong công nghệ phần mềm. Khi mới học C++ ở trường đại học, đôi khi chương trình mà bạn viết bạn có thể bị “sập” vì một vài lý do nào đó, nhưng đã có ai nói với bạn rằng nhiều sự cố trong số đó cũng là các lỗ hổng bảo mật tiềm ẩn chưa? Sự thiếu nhận thức về mối liên hệ giữa các lỗi và sự cố mà các nhà phát triển gặp phải, cũng như các vấn đề sự quan tâm đến rủi ro bảo mật từ sớm trong sự nghiệp của các nhà phát triển chính là biểu tượng cho việc bảo mật hiện vẫn chưa phải là mối quan tâm thứ yếu trong công nghệ phần mềm và cách thức môn học này được dạy ở giảng đường. Khi bắt tay vào một dự án mới, bạn phải chấp nhận rằng một trong những tiêu chí quan trọng nhất khi lựa chọn ngôn ngữ lập trình phải là "sự lựa chọn này sẽ ảnh hưởng như thế nào đến vấn đề bảo mật?".

WannaCry

Mất an toàn bộ nhớ hiện đang là một tai họa cho ngành công nghiệp phần mềm của chúng ta. Nhưng nó cũng không phải là nguyên nhân chính dẫn đến việc hàng tá các bản cập nhật Windows hoặc Firefox được phát hành ra nhằm mục đích sửa hàng “rổ” lỗ hổng bảo mật vốn có thể tránh được từ sớm hơn. Chúng ta cần thay đổi bản thân trong việc coi mỗi lỗ hổng không an toàn của bộ nhớ là một sự cố riêng lẻ, mà thay vào đó, hãy coi chúng là những vấn đề mang tính hệ thống sâu xa. Và sau đó, chúng ta cần đầu tư vào nghiên cứu kỹ thuật để làm thế nào chúng ta có thể xây dựng được các công cụ tốt hơn để giải quyết vấn đề này. Nếu thực hiện thành công sự thay đổi và đầu tư đó, chúng ta hoàn toàn có thể cải thiện đáng kể tính bảo mật cho người dùng và khiến các lỗ hổng bảo mật HeartBleed, WannaCry và các sự cố triệu đô trên iPhone trở nên ít phổ biến và ít nghiêm trọng hơn.

Xem thêm:

Thứ Ba, 15/01/2019 15:20
54 👨 1.162