Nhóm bảo mật Android thường xuyên nhận được các yêu cầu cung cấp thông tin về cách ngăn chặn các vấn đề bảo mật tiềm ẩn trên thiết bị Android. Đôi khi, chúng tôi cũng kiểm tra ngẫu nhiên các thiết bị và thông báo cho nhà sản xuất thiết bị cũng như các đối tác chịu ảnh hưởng về các vấn đề tiềm ẩn.
Trang này cung cấp các phương pháp hay nhất về bảo mật dựa trên kinh nghiệm của chúng tôi, mở rộng tài liệu Thiết kế cho bảo mật mà chúng tôi đã cung cấp cho nhà phát triển và bao gồm các thông tin chi tiết dành riêng cho việc xây dựng hoặc cài đặt phần mềm cấp hệ thống trên thiết bị.
Để hỗ trợ việc áp dụng các phương pháp hay nhất này, Nhóm bảo mật Android sẽ tích hợp các quy trình kiểm thử vào Bộ kiểm thử tính tương thích với Android (CTS) và Tìm lỗi mã nguồn Android (Android Lint) khi có thể. Chúng tôi khuyến khích các nhà triển khai thiết bị đóng góp các chương trình kiểm thử có thể giúp ích cho người dùng Android khác (xem các chương trình kiểm thử liên quan đến bảo mật tại root/cts/tests/tests/security/src/android/security/cts
).
Quy trình phát triển
Hãy áp dụng các phương pháp hay nhất sau đây trong quy trình và môi trường phát triển.
Xem lại mã nguồn
Việc xem xét mã nguồn có thể phát hiện nhiều vấn đề bảo mật, bao gồm cả những vấn đề được xác định trong tài liệu này. Android khuyến khích bạn thực hiện cả quy trình xem xét mã nguồn thủ công và tự động. Các phương pháp hay nhất:
- Chạy Android Lint trên tất cả mã ứng dụng bằng SDK Android và khắc phục mọi vấn đề đã xác định.
- Bạn nên phân tích mã gốc bằng một công cụ tự động có thể phát hiện các vấn đề về quản lý bộ nhớ, chẳng hạn như tràn bộ đệm và lỗi chênh lệch một bit.
- Hệ thống xây dựng Android hỗ trợ nhiều trình dọn dẹp LLVM, chẳng hạn như AddressSanitizer và UndefinedBehaviorSanitizer có thể được dùng cho mục đích này.
Sử dụng tính năng kiểm thử tự động
Kiểm thử tự động có thể phát hiện nhiều vấn đề bảo mật, bao gồm cả một số vấn đề được thảo luận bên dưới. Các phương pháp hay nhất:
- CTS thường xuyên được cập nhật bằng các bài kiểm thử bảo mật; hãy chạy phiên bản CTS mới nhất để xác minh khả năng tương thích.
- Thường xuyên chạy CTS trong suốt quá trình phát triển để phát hiện sớm các vấn đề và giảm thời gian khắc phục. Android sử dụng CTS như một phần của quá trình tích hợp liên tục trong quy trình tạo bản dựng tự động của chúng tôi, tạo nhiều lần mỗi ngày.
- Nhà sản xuất thiết bị nên tự động hoá quy trình kiểm thử bảo mật của giao diện, bao gồm cả việc kiểm thử bằng dữ liệu đầu vào có định dạng không chính xác (kiểm thử tìm lỗi mã nguồn).
Ký hình ảnh hệ thống
Chữ ký của hình ảnh hệ thống rất quan trọng để xác định tính toàn vẹn của thiết bị. Các phương pháp hay nhất:
- Thiết bị không được ký bằng khoá công khai.
- Các khoá dùng để ký thiết bị phải được quản lý theo cách nhất quán với các phương pháp tiêu chuẩn trong ngành để xử lý khoá nhạy cảm, bao gồm cả mô-đun bảo mật phần cứng (HSM) cung cấp quyền truy cập có giới hạn và có thể kiểm tra.
Ký ứng dụng (APK)
Chữ ký ứng dụng đóng vai trò quan trọng trong việc bảo mật thiết bị và được dùng để kiểm tra quyền cũng như cập nhật phần mềm. Khi chọn khoá để dùng cho việc ký ứng dụng, điều quan trọng là bạn phải xem xét liệu ứng dụng đó chỉ có trên một thiết bị hay phổ biến trên nhiều thiết bị. Các phương pháp hay nhất:
- Ứng dụng không được ký bằng khoá công khai.
- Các khoá dùng để ký ứng dụng phải được quản lý theo cách nhất quán với các phương pháp tiêu chuẩn trong ngành để xử lý khoá nhạy cảm, bao gồm cả một HSM cung cấp quyền truy cập có giới hạn và có thể kiểm tra.
- Không được ký ứng dụng bằng khoá nền tảng.
- Các ứng dụng có cùng tên gói không được ký bằng các khoá khác nhau. Điều này thường xảy ra khi tạo ứng dụng cho nhiều thiết bị, đặc biệt là khi sử dụng khoá nền tảng. Nếu ứng dụng không phụ thuộc vào thiết bị, hãy sử dụng cùng một khoá trên các thiết bị. Nếu ứng dụng dành riêng cho thiết bị, hãy tạo tên gói riêng biệt cho mỗi thiết bị và khoá.
Phát hành ứng dụng
Google Play giúp nhà sản xuất thiết bị cập nhật ứng dụng mà không cần thực hiện toàn bộ quá trình cập nhật hệ thống. Điều này có thể giúp đẩy nhanh quá trình phản hồi các vấn đề về bảo mật và phân phối các tính năng mới, cũng như cung cấp một cách để đảm bảo ứng dụng của bạn có tên gói riêng biệt. Các phương pháp hay nhất:
- Tải ứng dụng lên Google Play để cho phép cập nhật tự động mà không cần phải cập nhật đầy đủ qua mạng không dây (OTA). Người dùng không thể tải trực tiếp các ứng dụng đã tải lên nhưng chưa phát hành xuống, nhưng các ứng dụng này vẫn được cập nhật. Những người dùng đã cài đặt ứng dụng trước đó có thể cài đặt lại ứng dụng và/hoặc cài đặt trên các thiết bị khác.
- Tạo tên gói ứng dụng liên kết rõ ràng với công ty của bạn, chẳng hạn như bằng cách sử dụng nhãn hiệu của công ty.
- Bạn nên tải các ứng dụng do nhà sản xuất thiết bị phát hành lên Cửa hàng Google Play để tránh người dùng bên thứ ba mạo danh tên gói. Nếu nhà sản xuất thiết bị cài đặt một ứng dụng trên thiết bị mà không phát hành ứng dụng đó trên Cửa hàng Play, thì nhà phát triển khác có thể tải chính ứng dụng đó lên, sử dụng cùng một tên gói và thay đổi siêu dữ liệu cho ứng dụng. Khi ứng dụng được hiển thị cho người dùng, siêu dữ liệu không liên quan này có thể gây nhầm lẫn.
Phản hồi sự cố
Các bên bên ngoài phải có khả năng liên hệ với nhà sản xuất thiết bị về các vấn đề bảo mật dành riêng cho thiết bị. Bạn nên tạo một địa chỉ email có thể truy cập công khai để quản lý các sự cố bảo mật. Các phương pháp hay nhất:
- Tạo địa chỉ security@your-company.com hoặc địa chỉ tương tự và công bố địa chỉ đó.
- Nếu phát hiện thấy vấn đề bảo mật ảnh hưởng đến hệ điều hành Android hoặc thiết bị Android của nhiều nhà sản xuất thiết bị, bạn nên liên hệ với Nhóm bảo mật Android bằng cách gửi báo cáo lỗi bảo mật.
Triển khai sản phẩm
Hãy áp dụng các phương pháp hay nhất sau đây khi triển khai sản phẩm.
Tách biệt các quy trình gốc
Các quy trình gốc là mục tiêu thường xuyên nhất của các cuộc tấn công nâng cao đặc quyền, vì vậy, việc giảm số lượng quy trình gốc sẽ làm giảm nguy cơ nâng cao đặc quyền. CTS bao gồm một kiểm thử thông tin liệt kê các quy trình gốc. Các phương pháp hay nhất:
- Thiết bị phải chạy mã tối thiểu cần thiết dưới dạng thư mục gốc. Nếu có thể, hãy sử dụng quy trình Android thông thường thay vì quy trình gốc. ICS Galaxy Nexus chỉ có 6 quy trình gốc: vold, inetd, zygote, tf_daemon, ueventd và init. Nếu một quy trình phải chạy dưới quyền root trên thiết bị, hãy ghi lại quy trình đó trong yêu cầu tính năng AOSP để có thể xem xét công khai.
- Nếu có thể, mã gốc phải được tách biệt với dữ liệu không đáng tin cậy và truy cập thông qua IPC. Ví dụ: giảm chức năng gốc xuống một Dịch vụ nhỏ có thể truy cập được thông qua Binder và hiển thị Dịch vụ có quyền ký cho một ứng dụng có ít hoặc không có đặc quyền để xử lý lưu lượng truy cập mạng.
- Các quy trình gốc không được nghe trên ổ cắm mạng.
- Các quy trình gốc không được cung cấp thời gian chạy cho nhiều mục đích cho ứng dụng (ví dụ: máy ảo Java).
Tách biệt ứng dụng hệ thống
Nhìn chung, các ứng dụng cài đặt sẵn không nên chạy bằng UID hệ thống dùng chung. Tuy nhiên, nếu cần thiết để ứng dụng sử dụng UID dùng chung của hệ thống hoặc một dịch vụ đặc quyền khác, thì ứng dụng không được xuất bất kỳ dịch vụ, broadcast receiver hoặc nhà cung cấp nội dung nào mà ứng dụng bên thứ ba do người dùng cài đặt có thể truy cập. Các phương pháp hay nhất:
- Thiết bị phải chạy mã tối thiểu cần thiết dưới dạng hệ thống. Khi có thể, hãy sử dụng một quy trình Android có UID riêng thay vì sử dụng lại UID hệ thống.
- Nếu có thể, mã hệ thống phải được tách biệt với dữ liệu không đáng tin cậy và chỉ hiển thị IPC cho các quy trình đáng tin cậy khác.
- Các quy trình hệ thống không được nghe trên ổ cắm mạng.
Tách biệt các quy trình
Hộp cát của ứng dụng Android giúp tách biệt các ứng dụng với các quy trình khác trên hệ thống, bao gồm cả các quy trình gốc và trình gỡ lỗi. Trừ phi ứng dụng và người dùng bật tính năng gỡ lỗi theo cách cụ thể, thì không ứng dụng nào được vi phạm kỳ vọng đó. Các phương pháp hay nhất:
- Các quy trình gốc không được truy cập vào dữ liệu trong các thư mục dữ liệu ứng dụng riêng lẻ, trừ phi sử dụng phương thức gỡ lỗi Android được ghi nhận.
- Các quy trình gốc không được truy cập vào bộ nhớ của ứng dụng, trừ phi sử dụng một phương thức gỡ lỗi Android được ghi lại.
- Thiết bị không được chứa bất kỳ ứng dụng nào truy cập vào dữ liệu hoặc bộ nhớ của các ứng dụng hoặc quy trình khác.
Bảo mật tệp SUID
Các chương trình setuid mới không được các chương trình không đáng tin cậy truy cập. Các chương trình setuid thường là vị trí của các lỗ hổng có thể được dùng để truy cập vào quyền root, vì vậy, hãy cố gắng giảm thiểu khả năng cung cấp chương trình setuid cho các ứng dụng không đáng tin cậy. Các phương pháp hay nhất:
- Các quy trình SUID không được cung cấp một shell hoặc cửa sau có thể dùng để lách mô hình bảo mật của Android.
- Không người dùng nào được ghi vào các chương trình SUID.
- Các chương trình SUID không được đọc hoặc thực thi trên toàn cầu. Tạo một nhóm, hạn chế quyền truy cập vào tệp nhị phân SUID cho các thành viên của nhóm đó và đặt mọi ứng dụng có thể thực thi chương trình SUID vào nhóm đó.
- Các chương trình SUID là một nguồn phổ biến khiến người dùng can thiệp vào hệ thống của thiết bị. Để giảm rủi ro này, người dùng shell không được thực thi các chương trình SUID.
Trình xác minh CTS bao gồm một kiểm thử thông tin liệt kê các tệp SUID; một số tệp setuid không được phép theo mỗi kiểm thử CTS.
Cổng nghe bảo mật
Kiểm thử CTS không thành công khi thiết bị đang nghe trên bất kỳ cổng nào, trên bất kỳ giao diện nào. Trong trường hợp xảy ra lỗi, Android sẽ xác minh rằng bạn đang sử dụng các phương pháp hay nhất sau:
- Không được có cổng nghe trên thiết bị.
- Bạn phải có thể tắt cổng nghe mà không cần OTA. Đây có thể là thay đổi về cấu hình máy chủ hoặc cấu hình thiết bị của người dùng.
- Các quy trình gốc không được nghe trên bất kỳ cổng nào.
- Các quy trình thuộc sở hữu của UID hệ thống không được nghe trên bất kỳ cổng nào.
- Đối với IPC cục bộ sử dụng ổ cắm, ứng dụng phải sử dụng ổ cắm miền UNIX với quyền truy cập bị giới hạn ở một nhóm. Tạo một chỉ số mô tả tệp cho IPC và đặt thành +RW cho một nhóm UNIX cụ thể. Mọi ứng dụng khách đều phải nằm trong nhóm UNIX đó.
- Một số thiết bị có nhiều bộ xử lý (ví dụ: đài phát/mô-đun điều chế và giải điều chế tách biệt với bộ xử lý ứng dụng) sử dụng ổ cắm mạng để giao tiếp giữa các bộ xử lý. Trong những trường hợp như vậy, ổ cắm mạng dùng để giao tiếp giữa các bộ xử lý phải sử dụng giao diện mạng riêng biệt để ngăn các ứng dụng trái phép truy cập vào thiết bị (tức là sử dụng
iptables
để ngăn các ứng dụng khác truy cập vào thiết bị). - Các trình nền xử lý cổng nghe phải có khả năng chống lại dữ liệu bị định dạng không chính xác. Google có thể tiến hành kiểm thử tìm lỗi ngẫu nhiên đối với cổng bằng cách sử dụng ứng dụng không được uỷ quyền và nếu có thể thì cả ứng dụng được uỷ quyền. Mọi sự cố đều được gửi dưới dạng lỗi với mức độ nghiêm trọng thích hợp.
Ghi nhật ký dữ liệu
Việc ghi nhật ký dữ liệu làm tăng nguy cơ rò rỉ dữ liệu đó và làm giảm hiệu suất của hệ thống. Đã có nhiều sự cố bảo mật công khai xảy ra do các ứng dụng được cài đặt theo mặc định trên thiết bị Android ghi lại dữ liệu nhạy cảm của người dùng. Các phương pháp hay nhất:
- Ứng dụng hoặc dịch vụ hệ thống không được ghi nhật ký dữ liệu do các ứng dụng bên thứ ba cung cấp có thể chứa thông tin nhạy cảm.
- Ứng dụng không được ghi lại bất kỳ thông tin nhận dạng cá nhân (PII) nào trong quá trình hoạt động bình thường.
CTS bao gồm các bài kiểm thử để kiểm tra xem có thông tin có thể nhạy cảm trong nhật ký hệ thống hay không.
Giới hạn quyền truy cập vào thư mục
Thư mục mà mọi người đều có thể ghi có thể tạo ra các điểm yếu bảo mật và cho phép ứng dụng đổi tên các tệp đáng tin cậy, thay thế tệp hoặc tiến hành các cuộc tấn công dựa trên đường liên kết tượng trưng (kẻ tấn công có thể sử dụng đường liên kết tượng trưng đến một tệp để lừa một chương trình đáng tin cậy thực hiện các hành động không nên). Các thư mục có thể ghi cũng có thể ngăn việc gỡ cài đặt ứng dụng dọn dẹp đúng cách tất cả các tệp liên kết với ứng dụng.
Tốt nhất là các thư mục do hệ thống hoặc người dùng gốc tạo không được cho phép mọi người ghi. Các bài kiểm thử CTS giúp thực thi phương pháp hay nhất này bằng cách kiểm thử các thư mục đã biết.
Tệp cấu hình bảo mật
Nhiều trình điều khiển và dịch vụ dựa vào tệp cấu hình và dữ liệu được lưu trữ trong các thư mục như /system/etc
và /data
. Nếu các tệp này được xử lý bằng một quy trình đặc quyền và có thể ghi được, thì ứng dụng có thể khai thác lỗ hổng trong quy trình này bằng cách tạo nội dung độc hại trong tệp có thể ghi. Các phương pháp hay nhất:
- Các tệp cấu hình mà các quy trình đặc quyền sử dụng không được phép đọc được.
- Các tệp cấu hình mà các quy trình đặc quyền sử dụng không được phép ghi được.
Lưu trữ thư viện mã gốc
Mọi mã do các quy trình đặc quyền của nhà sản xuất thiết bị sử dụng phải nằm trong /vendor
hoặc /system
; các hệ thống tệp này được gắn ở chế độ chỉ có thể đọc khi khởi động. Cách hay nhất là các thư viện mà hệ thống hoặc các ứng dụng đặc quyền khác được cài đặt trên thiết bị sử dụng cũng phải nằm trong các hệ thống tệp này. Điều này có thể ngăn chặn một lỗ hổng bảo mật có thể cho phép kẻ tấn công kiểm soát mã mà một quy trình đặc quyền thực thi.
Giới hạn quyền truy cập của trình điều khiển thiết bị
Chỉ mã đáng tin cậy mới có quyền truy cập trực tiếp vào trình điều khiển. Nếu có thể, cấu trúc ưu tiên là cung cấp một trình nền có mục đích duy nhất để proxy các lệnh gọi đến trình điều khiển và hạn chế quyền truy cập của trình điều khiển vào trình nền đó. Tốt nhất là bạn không nên cho phép các nút thiết bị trình điều khiển có thể đọc hoặc ghi. Các bài kiểm thử CTS giúp thực thi phương pháp hay nhất này bằng cách kiểm tra các trường hợp đã biết của trình điều khiển bị lộ.
Tắt ADB
Cầu gỡ lỗi Android (adb) là một công cụ phát triển và gỡ lỗi có giá trị, nhưng được thiết kế để sử dụng trong các môi trường an toàn, được kiểm soát và không nên bật để sử dụng chung. Các phương pháp hay nhất:
- Theo mặc định, ADB phải bị tắt.
- ADB phải yêu cầu người dùng bật tính năng này trước khi chấp nhận kết nối.
Mở khoá trình tải khởi động
Nhiều thiết bị Android hỗ trợ tính năng mở khoá, cho phép chủ sở hữu thiết bị sửa đổi phân vùng hệ thống và/hoặc cài đặt hệ điều hành tuỳ chỉnh. Các trường hợp sử dụng phổ biến bao gồm cài đặt ROM của bên thứ ba và phát triển ở cấp hệ thống trên thiết bị. Ví dụ: chủ sở hữu thiết bị Google Nexus có thể chạy fastboot oem unlock
để bắt đầu quá trình mở khoá. Quá trình này sẽ hiển thị thông báo sau cho người dùng:
Mở khoá trình tải khởi động?
Nếu mở khoá trình tải khởi động, bạn sẽ có thể cài đặt phần mềm hệ điều hành tùy chỉnh trên thiết bị này.
Hệ điều hành tuỳ chỉnh không được kiểm thử giống như hệ điều hành gốc và có thể khiến thiết bị cũng như các ứng dụng đã cài đặt của bạn ngừng hoạt động đúng cách.
Để ngăn truy cập trái phép vào dữ liệu cá nhân của bạn, việc mở khoá trình tải khởi động cũng sẽ xoá tất cả dữ liệu cá nhân khỏi thiết bị của bạn ("đặt lại dữ liệu về trạng thái ban đầu").
Nhấn nút Tăng/Giảm âm lượng để chọn Có hoặc Không. Sau đó, nhấn nút Nguồn để tiếp tục.
Có: Mở khoá trình tải khởi động (có thể làm mất hiệu lực bảo hành)
Không: Không mở khoá trình tải khởi động và khởi động lại thiết bị.
Cách tốt nhất là các thiết bị Android có thể mở khoá phải xoá tất cả dữ liệu người dùng một cách an toàn trước khi mở khoá. Việc không xoá đúng cách tất cả dữ liệu khi mở khoá có thể cho phép kẻ tấn công ở gần có được quyền truy cập trái phép vào dữ liệu mật của người dùng Android. Để ngăn việc tiết lộ dữ liệu người dùng, thiết bị hỗ trợ tính năng mở khoá phải triển khai tính năng này đúng cách (chúng tôi đã thấy nhiều trường hợp nhà sản xuất thiết bị triển khai tính năng mở khoá không đúng cách). Quy trình mở khoá được triển khai đúng cách có các thuộc tính sau:
- Khi người dùng xác nhận lệnh mở khoá, thiết bị phải bắt đầu xoá dữ liệu ngay lập tức. Bạn không được đặt cờ
unlocked
cho đến khi quá trình xoá an toàn hoàn tất. - Nếu không thể hoàn tất quá trình xoá an toàn, thiết bị phải ở trạng thái khoá.
- Nếu thiết bị khối cơ bản hỗ trợ, bạn nên sử dụng
ioctl(BLKSECDISCARD)
hoặc tương đương. Đối với các thiết bị eMMC, điều này có nghĩa là sử dụng lệnh Xoá an toàn hoặc Cắt bớt an toàn. Đối với eMMC phiên bản 4.5 trở lên, điều này có nghĩa là sử dụng thao tác Xoá hoặc Cắt thông thường, theo sau là thao tác Làm sạch. - Nếu thiết bị khối cơ bản không hỗ trợ
BLKSECDISCARD
, bạn phải sử dụngioctl(BLKDISCARD)
. Trên các thiết bị eMMC, đây là thao tác Cắt thông thường. - Nếu
BLKDISCARD
không được hỗ trợ, bạn có thể ghi đè các thiết bị khối bằng toàn bộ số 0. - Người dùng cuối phải có lựa chọn yêu cầu xoá dữ liệu người dùng trước khi cài đặt ROM cho một phân vùng. Ví dụ: trên các thiết bị Nexus, việc này được thực hiện thông qua lệnh
fastboot oem lock
. - Thiết bị có thể ghi lại, thông qua efuse hoặc cơ chế tương tự, liệu thiết bị có được mở khoá và/hoặc khoá lại hay không.
Các yêu cầu này đảm bảo rằng tất cả dữ liệu sẽ bị huỷ sau khi hoàn tất thao tác mở khoá. Việc không triển khai các biện pháp bảo vệ này được coi là một lỗ hổng bảo mật ở mức độ trung bình.
Sau đó, bạn có thể khoá lại một thiết bị đã mở khoá bằng lệnh fastboot oem lock
. Việc khoá trình tải khởi động sẽ bảo vệ dữ liệu người dùng bằng hệ điều hành tuỳ chỉnh mới giống như cách bảo vệ dữ liệu người dùng bằng hệ điều hành của nhà sản xuất thiết bị ban đầu (ví dụ: dữ liệu người dùng sẽ bị xoá nếu thiết bị được mở khoá lại).