Kategoria OWASP: MASVS-CODE: Jakość kodu
Przegląd
Aplikacje na Androida mogą korzystać z kodu natywnego napisanego w językach takich jak C i C++ w przypadku określonych funkcji. Jeśli jednak aplikacja korzysta z interfejsu Java Native Interface (JNI) do interakcji z tym kodem natywnym, może być narażona na luki w zabezpieczeniach, takie jak przepełnienie bufora i inne problemy, które mogą występować w implementacji kodu natywnego.
Wpływ
Pomimo bardzo pozytywnych efektów, takich jak optymalizacja wydajności i zaciemnianie kodu, używanie kodu natywnego w aplikacjach na Androida może mieć negatywny wpływ na bezpieczeństwo. Języki kodu natywnego, takie jak C/C++, nie mają funkcji bezpieczeństwa pamięci, które są dostępne w przypadku języków Java/Kotlin. Z tego powodu są podatne na luki w zabezpieczeniach, takie jak przepełnienia bufora, błędy odwołania do pamięci po jej zwolnieniu i inne problemy z uszkodzeniem pamięci, które mogą prowadzić do awarii lub wykonywania dowolnego kodu. Jeśli w komponencie kodu natywnego występuje luka w zabezpieczeniach, może ona narazić na niebezpieczeństwo całą aplikację, nawet jeśli pozostała część jest bezpiecznie napisana w języku Java.
Środki ograniczające ryzyko
Wskazówki dotyczące programowania i kodowania
- Wytyczne dotyczące bezpiecznego kodowania: w przypadku projektów w językach C/C++ należy przestrzegać ustalonych standardów bezpiecznego kodowania (np. CERT, OWASP), aby ograniczyć luki w zabezpieczeniach, takie jak przepełnienie bufora, przepełnienie liczb całkowitych i ataki z użyciem ciągów formatujących. Priorytetowo traktuj biblioteki, takie jak Abseil, które są znane z jakości i bezpieczeństwa. Jeśli to możliwe, rozważ używanie języków bezpiecznych pod względem zarządzania pamięcią, takich jak Rust, które zapewniają wydajność porównywalną z C/C++.
- Weryfikacja danych wejściowych: rygorystycznie weryfikuj wszystkie dane wejściowe otrzymywane ze źródeł zewnętrznych, w tym dane wejściowe użytkownika, dane sieciowe i pliki, aby zapobiegać atakom typu „wstrzykiwanie kodu” i innym lukom w zabezpieczeniach.
Zwiększanie bezpieczeństwa opcji kompilacji
Biblioteki natywne korzystające z formatu ELF można zabezpieczyć przed różnymi lukami w zabezpieczeniach, aktywując mechanizmy ochrony, takie jak ochrona stosu (Canary), przenoszenie tylko do odczytu (RELRO), zapobieganie wykonywaniu danych (NX) i wykonywalne pliki niezależne od pozycji (PIE). Wygodnie jest to, że opcje kompilacji Android NDK domyślnie włączają wszystkie te zabezpieczenia.
Aby sprawdzić wdrożenie tych mechanizmów zabezpieczeń w pliku binarnym, możesz użyć narzędzi takich jak hardening-check lub 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
Sprawdzaj, czy biblioteki zewnętrzne nie są podatne na ataki.
Wybierając biblioteki innych firm, priorytetowo traktuj te, które mają dobrą reputację w społeczności deweloperów. Zasoby takie jak indeks pakietów SDK Google Play mogą pomóc Ci w znalezieniu cenionych i godnych zaufania bibliotek. Upewnij się, że biblioteki są aktualizowane do najnowszych wersji, i aktywnie wyszukuj znane luki w zabezpieczeniach, korzystając z zasobów takich jak bazy danych Exploit-DB. Wyszukiwanie w internecie za pomocą słów kluczowych, takich jak [library_name] vulnerability lub [library_name] CVE, może ujawnić ważne informacje dotyczące bezpieczeństwa.
Zasoby
- CWE-111: Direct Use of Unsafe JNI
- Baza danych luk w zabezpieczeniach
- Sprawdzanie plików binarnych pod kątem funkcji wzmacniania zabezpieczeń
- Sprawdzanie ustawień zabezpieczeń plików binarnych za pomocą pwntools
- Wzmacnianie zabezpieczeń plików binarnych w systemie Linux
- Wzmacnianie zabezpieczeń plików binarnych ELF za pomocą funkcji Relocation Read-Only (RELRO)
- Mechanizmy ochrony plików binarnych OWASP
- SEI CERT Coding Standards
- Przewodnik dla programistów OWASP
- Google Play SDK Index
- Android NDK
- Wprowadzenie do języka Rust na Androidzie
- Abseil (C++ Common Libraries)
- Wymuszanie PIE przez linker