Danh mục OWASP: MASVS-CODE: Chất lượng mã
Tổng quan
Các ứng dụng Android có thể tận dụng mã gốc được viết bằng các ngôn ngữ như C và C++ cho các chức năng cụ thể. Tuy nhiên, khi một ứng dụng sử dụng Giao diện gốc của Java (JNI) để tương tác với mã gốc này, ứng dụng đó có khả năng gặp phải các lỗ hổng như tràn bộ nhớ đệm và các vấn đề khác có thể xuất hiện trong quá trình triển khai mã gốc.
Tác động
Mặc dù có những tác động rất tích cực như tối ưu hoá hiệu suất và làm rối mã nguồn, nhưng việc sử dụng mã gốc trong các ứng dụng Android có thể gây ra những tác động tiêu cực đến tính bảo mật. Các ngôn ngữ mã gốc như C/C++ thiếu các tính năng an toàn bộ nhớ của Java/Kotlin, khiến chúng dễ bị các lỗ hổng bảo mật như tràn bộ nhớ đệm, lỗi sử dụng sau khi giải phóng và các vấn đề khác về hỏng bộ nhớ – dẫn đến sự cố hoặc thực thi mã tuỳ ý. Ngoài ra, nếu có một lỗ hổng trong thành phần mã gốc, thì lỗ hổng đó có thể làm ảnh hưởng đến toàn bộ ứng dụng, ngay cả khi phần còn lại được viết một cách an toàn bằng Java.
Giải pháp giảm thiểu
Hướng dẫn phát triển và lập trình
- Nguyên tắc viết mã an toàn: Đối với các dự án C/C++, hãy tuân thủ các tiêu chuẩn viết mã an toàn đã được thiết lập (ví dụ: CERT, OWASP) để giảm thiểu các lỗ hổng bảo mật như tràn bộ nhớ đệm, tràn số nguyên và các cuộc tấn công bằng chuỗi định dạng. Ưu tiên các thư viện như Abseil, vốn nổi tiếng về chất lượng và tính bảo mật. Bất cứ khi nào có thể, hãy cân nhắc việc sử dụng các ngôn ngữ an toàn đối với bộ nhớ như Rust. Ngôn ngữ này có hiệu suất tương đương với C/C++.
- Xác thực dữ liệu đầu vào: Xác thực nghiêm ngặt tất cả dữ liệu đầu vào nhận được từ các nguồn bên ngoài, bao gồm cả hoạt động đầu vào của người dùng, dữ liệu mạng và tệp, để ngăn chặn các cuộc tấn công tiêm mã và các lỗ hổng bảo mật khác.
Tăng cường các lựa chọn biên dịch
Các thư viện gốc sử dụng định dạng ELF có thể được tăng cường khả năng chống lại nhiều loại lỗ hổng bằng cách kích hoạt các cơ chế bảo vệ như bảo vệ ngăn xếp (Canary), chỉ đọc khi di dời (RELRO), ngăn chặn thực thi dữ liệu (NX) và các tệp thực thi độc lập với vị trí (PIE). Rất may là các lựa chọn biên dịch Android NDK đã bật tất cả các biện pháp bảo vệ này theo mặc định.
Để xác minh việc triển khai các cơ chế bảo mật này trong một tệp nhị phân, bạn có thể sử dụng các công cụ như hardening-check hoặc pwntools.
Bash
$ pwn checksec --file path/to/libnativecode.so
Arch: aarch64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
Xác minh rằng các thư viện bên thứ ba không dễ bị tấn công
Khi chọn thư viện bên thứ ba, hãy ưu tiên sử dụng những thư viện có danh tiếng tốt trong cộng đồng phát triển. Các tài nguyên như Chỉ mục SDK Google Play có thể giúp bạn xác định những thư viện đáng tin cậy và được đánh giá cao. Đảm bảo bạn luôn cập nhật các thư viện lên phiên bản mới nhất và chủ động tìm kiếm mọi lỗ hổng bảo mật đã biết liên quan đến các thư viện đó bằng cách sử dụng các tài nguyên như cơ sở dữ liệu của Exploit-DB. Bạn có thể tìm kiếm trên web bằng các từ khoá như [library_name] vulnerability hoặc [library_name] CVE để biết thông tin bảo mật quan trọng.
Tài nguyên
- CWE-111: Direct Use of Unsafe JNI (CWE-111: Sử dụng trực tiếp JNI không an toàn)
- Cơ sở dữ liệu khai thác
- Kiểm tra các tệp nhị phân để tìm các tính năng tăng cường bảo mật
- Kiểm tra chế độ cài đặt bảo mật nhị phân bằng pwntools
- Tăng cường bảo mật cho tệp nhị phân Linux
- Tăng cường bảo mật cho các tệp nhị phân ELF bằng cách sử dụng tính năng Chỉ đọc khi di dời (RELRO)
- Cơ chế bảo vệ nhị phân của OWASP
- Tiêu chuẩn mã hoá SEI CERT
- Hướng dẫn dành cho nhà phát triển của OWASP
- Chỉ mục SDK của Google Play
- Android NDK
- Giới thiệu về Rust trên Android
- Abseil (Thư viện chung C++)
- Trình liên kết sẽ thực thi PIE