+4

Hiểm họa khôn lường khi "code bằng AI"

I. Giới thiệu

Thời gian gần đây, AI nổi lên mạnh mẽ như một trend rất phát triển và ngày càng được sử dụng rộng rãi. Đặc biệt trong lĩnh vực phát triển phần mềm, AI ngày càng trở lên "hot" với những từ khóa : "ai thay thể lập trình viên", "Ai và tương lai lập trình viên"...

image.png

Vậy liệu AI có thực sự thay thể được con người và liệu chúng có thực sự an toàn. Chúng ta cùng tìm hiểu bài viết dưới đây nhé!!!

Các mô hình AI được huấn luyện để tạo ra những đoạn code mẫu thường sử dụng các mô hình cơ sở dữ liệu lớn với nhiệm vụ chính là tạo ra mã có thể hoạt động. Các lập trình viên ngày nay thường sử dụng AI để tạo ra một số đoạn code cho những module hay tính năng cần sử dụng trong hệ thống. Một số công cụ phổ biến có thể liệt kê ở đây gồm: ChatGPT, Github Copilot, Google Cloud Code – Duet AI, Amazon CodeWhisperer... Lợi ích của các công cụ là cho chúng ta kết quả nhanh, có những đoạn code có thể hoạt động theo đúng yêu cầu. Bên cạnh đó nhiều vấn đề bảo mật cũng được hạn chế do AI đã có thể sử dụng những đoạn code an toàn hơn mà không làm ảnh hưởng đến hiệu suất (ví dụ: Lỗi SQL Injection có thể tránh bằng cách không nối trực tiếp đầu vào hoặc tham số của người dùng vào truy vấn). Vì vậy, những vấn đề này có thể được loại bỏ nếu mã được viết theo cách an toàn.

Tuy nhiên, cũng có nhiều vấn đề bảo mật phụ thuộc vào ngữ cảnh, có thể an toàn khi được sử dụng trong hàm đó nhưng lại trở thành lỗ hổng khi nhận dữ liệu từ đầu vào bên ngoài. Những trường hợp này thường khó được phân biệt qua tập dữ liệu mà AI được huấn luyện. Trong những lỗ hổng như vậy, cách sử dụng code cụ thể thường phụ thuộc vào các phần khác của code và mục đích tổng thể của ứng dụng.

II. Phân tích một số trường hợp thiếu an toàn

1. Fetching Files from User Input – Arbitrary File Read

Nhiều ứng dụng sử dụng code để lấy một file dựa trên tên file. Nếu code không được xử lý lọc dữ liệu đầu vào một cách an toàn có thể bị dẫn đến lỗ hổng "directory traversal" - đọc file tùy ý một cách trái phép trên máy chủ. Vấn đề xử lý dữ liệu đầu vào gần như là bắt buộc với lập trình viên khi phát triển tính năng liên quan đến việc upload hoặc đọc file. Tuy nhiên, AI lại khó có thể xử lý vấn đề này do một số tập dữ liệu không yêu cầu xử lý đường dẫn file.

Ví dụ AI Tool Suggestion (Google Cloud Code – Duet AI):

image.png

Ở đây, AI gợi ý sử dụng hàm send_file của Flask, công cụ code ra đoạn code và nhận trực tiếp input của người dùng. Tuy nhiên, tài liệu Flask cảnh báo rằng "Không bao giờ truyền trực tiếp đường dẫn file do người dùng cung cấp."

Khuyến nghị

Sử dụng hàm send_from_directory của Flask để giảm thiểu rủi ro, tránh bị lỗ hổng "directory traversal" và giới hạn chỉ lấy tệp từ thư mục được chỉ định sẵn.

image.png

2. Comparing Secret Tokens – Type Juggling/Coercion

Trong các ngôn ngữ như PHP hoặc NodeJS, so sánh giữa các kiểu dữ liệu khác nhau có thể dẫn đến lỗi bảo mật nếu không được kiểm tra chặt chẽ. Lỗ hổng PHP Type Juggling là một lỗ hổng bảo mật trong mã nguồn PHP, nó cho phép kẻ tấn công thực hiện các cuộc tấn công đánh lừa bằng cách sử dụng các giá trị không mong muốn. Lỗ hổng này xảy ra khi PHP tự động chuyển đổi kiểu dữ liệu của một biến sang kiểu dữ liệu khác mà không kiểm tra tính hợp lệ của giá trị đó. image.png

Ví dụ AI Tool Suggestion (Amazon CodeWhisperer):

image.png

AI Tool Suggestion (Amazon CodeWhisperer) gợi ý sử dụng so sánh (==), điều này có thể dẫn đến lỗi "type juggling". Dữ liệu người dùng truyền vào $data[secret_token] được so sánh trực tiếp với string "secret_token". Trong trường hợp kẻ tấn công không biết chuỗi "secret_token", có thể truyền vào $data[secret_token]=True, và kết quả trả về là "Success";

**Khuyến nghị: **

Sử dụng so sánh một cách chặt chẽ và an toàn (===) để đảm bảo an toàn ngăn chặn lỗ hổng "type juggling"

image.png

3. Forgot Password Mechanism – Unicode Case Mapping Collisions

Trong một số trường hợp, việc chuyển đổi input của người dùng sang chữ thường hoặc chữ hoa có thể tạo ra lỗi ánh xạ Unicode, dẫn đến lỗ hổng bảo mật nguy hiểm. Các lỗ hổng trong cơ chế “Quên mật khẩu” rất phổ biến trong các ứng dụng SaaS và là nguyên nhân sâu xa đằng sau các CVE như CVE-2019-19844 (Django), CVE-2023-7028 (GitLab) và nhiều lỗ hổng khác.

Cụ thể, lỗ hổng Unicode Case Mapping Collision xảy ra khi đầu vào của người dùng được chuyển đổi thành chữ hoa hoặc chữ thường trong một biểu thức so sánh, trong khi giá trị ban đầu của đầu vào vẫn được sử dụng trong mã. Một số ký tự khác nhau có thể dẫn đến mã ký tự giống nhau khi chuyển đổi. Ví dụ: Ký tự “ß” và “SS” đều được chuyển đổi thành “0x00DF” khi chuyển sang chữ hoa. Những lỗi này rất khó nhận ra, đặc biệt khi có nhiều cách triển khai khác nhau.

Ví dụ AI Tool Suggestion (GitHub Copilot):

image.png

AI gợi ý xử lý email bằng cách chuyển sang chữ thường để kiểm tra user tồn tại trong hệ thống. Nhưng sau đó lại sử dụng phiên bản email gốc (không được chuyển đổi sang chữ thường) làm địa chỉ nhận email khôi phục mật khẩu.

image.png

Ví dụ, giả sử kẻ tấn công sở hữu hộp thư email “miKe@example.com” (trong đó “K” là ký tự Unicode Kelvin Sign) và sử dụng địa chỉ email này trong cơ chế Quên Mật Khẩu. Các địa chỉ email “miKe@example.com” và “mike@example.com” là 2 email khác nhau hoàn toàn nhưng sau khi được chuyển đổi sang chữ thường, chúng sẽ giống nhau. Từ đó kẻ tấn công có thể nhận được email khôi phục mật khẩu của nạn nhân.

image.png

Chữ "K" trong 2 bộ ký tự khác nhau nhưng khi dùng lower() thì sẽ trùng nhau

Khuyến nghị:

  • Địa chỉ email được sử dụng để tìm tài khoản người dùng phải hoàn toàn khớp với địa chỉ email nhận email khôi phục (tức là tham số send_email cũng phải sử dụng email.lower()).
  • Ngoài ra, như một biện pháp phòng ngừa, nên sử dụng giá trị email đã được lưu trữ trên máy chủ thay vì sử dụng giá trị do người dùng cung cấp.

4. Generating Configuration File – Bad Security Practices

Một chủ đề khác có thể gây nhầm lẫn cho các công cụ AI là việc viết các tệp cấu hình, đặc biệt đối với các hạ tầng cloud phức tạp. Nguyên nhân chính là mặc dù có các hướng dẫn thực hành bảo mật tốt nhất, nhưng không phải ai cũng tuân thủ chúng, và trong một số trường hợp, cần phải đi ngược lại các hướng dẫn này. Những đoạn mã không tuân theo tiêu chuẩn này có thể lọt vào tập dữ liệu huấn luyện của AI. Kết quả là, các gợi ý tự động của AI có thể vi phạm các nguyên tắc bảo mật được khuyến nghị.

Trong ví dụ dưới đây, chúng tôi sẽ tạo một tệp cấu hình cho một Kubernetes Pod, đơn vị thực thi nhỏ nhất trong Kubernetes.

AI Tool Suggestion (Blackbox AI Code Generation):

image.png

Gợi ý này tạo ra phần capabilities này về cơ bản tương đương với việc chạy Pod dưới quyền root.

Khuyến nghị:

Sử dụng nguyên tắc đặc quyền tối thiểu, loại bỏ tất cả quyền mặc định và chỉ thêm quyền thực sự cần thiết. Trong ví dụ có thể là user MAC_ADMIN

image.png

5. Configuration Objects – Inconsistencies Leading to Insecure Deserialization

Nhiều lỗ hổng yêu cầu định nghĩa một đối tượng cấu hình, nhằm quyết định cách ứng dụng xử lý các thành phần cần thiết. Ví dụ thư viện deserialization JSON của Newtonsoft trong C#. Thư viện này có thể được sử dụng một cách an toàn hoặc không an toàn, tùy thuộc vào cấu hình của đối tượng JsonSerializerSettings, đặc biệt là thuộc tính TypeNameHandling.

Ví dụ AI Tool Suggestions (Amazon CodeWhisperer):

image.png

image.png

AI gợi ý sử dụng TypeNameHandling là "Auto" hoặc "All", điều này có thể dẫn đến lỗ hổng insecure deserialization.

**Khuyến nghị: **

Sử dụng giá trị mặc định "None".

image.png

6. Secure Code Request Use Case: Reading Files – Avoiding Directory Traversal

Giống như trường hợp đầu tiên (Lấy tệp từ đầu vào người dùng), ví dụ này yêu cầu AI tạo ra một đoạn code "an toàn". để chống lại lỗ hổng Directory Traversal. Tuy nhiên việc gợi ý từ AI chưa thực sự tốt và vẫn có thể bị bypass.

Ví dụ AI Tool Suggestion (GitHub Copilot):

image.png

AI đề xuất kiểm tra bảo mật khá sơ sài, chỉ ngăn cản chuỗi ký tự ../ để ngăn chặn lỗ hổng "directory traversal". Việc này là có hiệu quả tuy nhiên chưa triệt để. Kẻ tấn công có thể bypass bằng một số kỹ thuật sau:

  • Sử dụng một đường dẫn tuyệt đối, chẳng hạn /etc/passwd.
  • Sử dụng kỹ thuật URL encoded: ../ sẽ trở thành %2e%2e%2f
  • Sử dụng kỹ thuật double encode : ../ sẽ trở thành %252E%252E%252F

Khuyến nghị

image.png

Sử dụng hàm secure_file_read nhận tham số tên tệp (tương đối) cùng với một thư mục (ví dụ: safe_dir) nơi tên tệp nên nằm trong đó (và không được vượt ra ngoài thư mục này). Kết hợp thư mục an toàn (safe_dir) và tên tệp để tạo một đường dẫn tuyệt đối. Sử dụng hàm realpath để chuẩn hóa đường dẫn. Kết quả là hàm chỉ cho phép trả về nội dung tệp nếu đường dẫn đã chuẩn hóa bắt đầu bằng thư mục an toàn đã chuẩn hóa.

7. Secure Code Request – File Upload – Restricted Extensions List

Một trường hợp sử dụng phổ biến là chỉ chấp nhận một số loại tệp cụ thể dựa trên phần mở rộng của chúng khi tải lên.

Ví dụ AI Tool Suggestion (Blackbox AI Code Generation):

AI tạo một đoạn mã trong Python để lọc các phần mở rộng tệp nguy hiểm. Đoạn mã đề xuất tách phần mở rộng tệp và so sánh nó với danh sách phần mở rộng bị cấm.

image.png

Vấn đề ở đây là trên hệ điều hành Windows, cơ chế Windows filename conventions được thiết lập để các tên tệp không được phép kết thúc bằng một dấu chấm (.).

Vậy với đoạn code trên, nếu người dùng cung cấp một tệp với phần mở rộng độc hại kết thúc bằng một dấu chấm (ví dụ: example.exe.), dấu chấm sẽ bị bỏ qua. Điều này có thể được sử dụng để vượt qua bộ lọc của hệ thống.

Khuyến nghị:

Phương pháp an toàn hơn là sử dụng whitelist, chỉ kiểm tra phần mở rộng tệp với các phần mở rộng được phép. Nếu bắt buộc phải sử dụng danh sách đen (blacklist), cần thực hiện các bước sau:

image.png

  • Xóa bỏ tất cả các ký tự không phải chữ và số từ phần mở rộng.
  • Tạo một tên tệp mới, đảm bảo kiểm soát hoàn toàn đầu vào từ người dùng.

Kết luận

Với những ví dụ đưa ra ở trên chúng ta có thể thấy dù AI mang lại nhiều lợi ích trong việc phát triển mã nguồn, nhưng nó cũng có thể tạo ra các lỗ hổng nghiêm trọng nếu không được giám sát cẩn thận. Các nhà phát triển cần xem xét kỹ lưỡng và chịu trách nhiệm bảo đảm mã được an toàn trước khi triển khai.. Lời khuyên ở đây là:

  1. Thực hiện kiểm tra thủ công: Đảm bảo mọi mã AI tạo ra đều được kiểm tra lại hoặc nhờ chuyên gia bảo mật rà soát.
  2. Sử dụng các công cụ rà quét lỗ hổng bảo mật để scan source code giúp phát hiện các lỗ hổng bảo mật

All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.