Kategoria OWASP: MASVS-CODE: jakość kodu
Omówienie
Aplikacje na Androida mogą wykorzystywać kod natywny napisany w językach takich jak C i C++, by obsługiwać określone funkcje. Jednak gdy aplikacja używa natywnego interfejsu Java (JNI) do interakcji z tym kodem natywnym, może być narażona na luki w zabezpieczeniach, takie jak przepełnienia bufora i inne problemy, które mogą występować w implementacji kodu natywnego.
Wpływ
Pomimo bardzo pozytywnych skutków, takich jak optymalizacja wydajności i zaciemnianie, korzystanie z 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 Java/Kotlin, przez co są podatne na luki w zabezpieczeniach, takie jak przepełnienia bufora, błędy use-after-free i inne problemy z uszkodzoną pamięcią, które mogą prowadzić do awarii lub niekontrolowanego wykonania kodu. Poza tym jeśli w komponencie kodu natywnego znajduje się luka, może ona potencjalnie zagrażać bezpieczeństwu całej aplikacji, nawet jeśli pozostała część jest zapisana w bezpieczny sposób w języku Java.
Łagodzenie
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) w celu zminimalizowania luk w zabezpieczeniach, takich jak przepełnienie bufora, przepełnienie liczby całkowitej i ataki na formatowanie ciągu znaków. Ustaw priorytety dla bibliotek, takich jak Abseil, które są znane z jakości i bezpieczeństwa. W miarę możliwości staraj się wdrażać języki bezpieczne w pamięci, takie jak Rust. Wydajność ta jest porównywalna z językiem C/C++.
- Weryfikacja danych wejściowych: rygorystyczna weryfikacja wszystkich danych wejściowych otrzymywanych ze źródeł zewnętrznych, w tym danych wejściowych użytkownika, danych sieciowych i plików, w celu zapobiegania atakom polegającym na wstrzykiwaniu kodu i innym podatnościom.
Zaostrzenie opcji kompilacji
Biblioteki natywne korzystające z formatu ELF mogą być zabezpieczone przed różnymi podatnościami poprzez włączenie mechanizmów ochronnych, takich jak ochrona stosu (Canary), przeniesienie tylko do odczytu (RELRO), zapobieganie wykonywaniu danych (NX) i pliki wykonywalne niezależne od pozycji (PIE). Dla wygody opcje kompilacji Androida NDK są już domyślnie włączone dla wszystkich tych zabezpieczeń.
Aby sprawdzić implementację tych mechanizmów zabezpieczeń w plikach binarnych, 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
Sprawdź, czy biblioteki innych firm nie są podatne na ataki
Wybierając biblioteki innych firm, stawiaj na te, które mają dobrą reputację w społeczności programistów. Materiały takie jak indeks pakietów SDK Google Play mogą pomóc Ci znaleźć godne zaufania biblioteki. Zadbaj o to, aby biblioteki były zawsze aktualizowane do najnowszych wersji, i proaktywnie szukaj znanych luk związanych z nimi, korzystając z zasobów takich jak bazy danych Exploit-DB. Wyszukiwanie w internecie przy użyciu słów kluczowych takich jak [library_name] vulnerability
lub [library_name] CVE
może ujawnić kluczowe informacje dotyczące bezpieczeństwa.
Materiały
- CWE-111: bezpośrednie użycie niebezpiecznego JNI
- Baza danych o lukach
- Sprawdzanie plików binarnych pod kątem funkcji wzmacniających zabezpieczenia
- Sprawdzanie ustawień zabezpieczeń binarnych za pomocą narzędzia pwntools
- Zabezpieczanie binarnych plików wykonywalnych w systemie Linux
- Zabezpieczanie binarek ELF za pomocą funkcji Relocation Read-Only (RELRO)
- Mechanizmy ochrony binarnej OWASP
- standardy kodowania SEI CERT,
- Przewodnik dla programistów OWASP
- Google Play SDK Index
- Android NDK
- Wprowadzenie do Rusta na Androida
- Abseil (biblioteki wspólne C++)
- Tag łączący jest wymuszany przez PIE