Programowanie

Jak zabezpieczamy aplikacje na Androida?

8 minut czytania
Komentarze

Witajcie w kolejnym odcinku. Dzisiaj porozmawiamy sobie o bezpieczeństwie. Jak zawsze postaram się opisać wszystko w sposób lekki i przyjemny. Tak więc zapraszam do czytania!

Po co zabezpieczać aplikacje?

W przypadku aplikacji mobilnych zagrożenia mogą nadejść z kilku stron. Najważniejszą kwestią jest oczywiście zadbanie o bezpieczeństwo samych użytkowników. Nie chcielibyśmy przecież dopuścić do sytuacji, w której ktoś wykradnie nam ich dane. Takie wydarzenie poważnie obniża zaufanie do naszej aplikacji. Oprócz tego w pewnym stopniu musimy również chronić siebie, a właściwie naszą pracę. Bardzo powszechne są techniki utrudniające innym programistom wykradnięcie i splagiatowanie naszego kodu źródłowego. W przypadku popularnych aplikacji występuje jeszcze jedno ryzyko — ktoś może zmodyfikować naszą aplikację na swoje potrzeby (na przykład dodając kod szpiegujący) i dystrybuować ją dla naszych użytkowników, narażając ich na potencjalne niebezpieczeństwo. W tym artykule przedstawię kilka zabezpieczeń, pomagających uchronić naszą aplikację przed wymienionymi przeze mnie zagrożeniami.

OAuth — autoryzacja zapytań serwerowych

Jest to typ zabezpieczenia, z którym styka się niemal każdy z użytkowników smartfona. Zastanawialiście się nieraz, jak to się dzieje, że po otwarciu aplikacji takich jak Facebook, Gmail czy Youtube jesteście od razu zalogowani i nie musicie za każdym razem wpisywać hasła? To nie jest tak, że wasze dane do logowania są trzymane gdzieś w pamięci telefonu — to byłoby zbyt niebezpieczne. Za takie automatyczne logowanie odpowiada właśnie OAuth. Jest to otwarty standard, umożliwiający autoryzację zapytań wysyłanych na serwer (i nie tylko). W ten sposób serwer jest w stanie zidentyfikować konkretnego użytkownika. Nie chcę się zagłębiać w szczegóły techniczne, bo są one dość nudne. Wygląda to tak, że login i hasło wysyłamy tylko w przypadku logowania, jeśli serwer pomyślnie weryfikuje te dane, odsyła nam tak zwany token autoryzacyjny (dość długi ciąg znaków). Następnie do każdego zapytania dołączamy nasz token, w ten sposób serwer wie, że zapytanie zostało wysłane przez autoryzowanego użytkownika, a nie kogoś innego.

Blokada roota

Jeśli miałeś kiedykolwiek zrootowany telefon, pewnie spotkałeś się z sytuacją, że nie mogłeś uruchomić niektórych aplikacji (przeważnie bankowych). Dlaczego programiści blokują działanie programów na telefonach z rootem? Chodzi przede wszystkim o zabezpieczenie użytkowników oraz własnych interesów. Dotyczy to szczególnie aplikacji, w których podajemy jakieś dane dotyczące płatności (na przykład dane kart płatniczych). Łatwo wyobrazić sobie sytuację, w której jakiś wirus podsłucha dane karty płatniczej użytkownika, które podał w naszej aplikacji. W takim przypadku bardzo prawdopodobne, że użytkownik winą będzie obarczał nas jako twórców aplikacji, dlatego wiele firm profilaktycznie blokuje działanie na zrootowanych telefonach. Dodatkowo root daje większe możliwości analizowania aplikacji działających na urządzeniu, co może prowadzić do odkrycia i złamania naszych zabezpieczeń. 

ProGuard — zabezpieczenia przed programistami

ProGuard jest narzędziem, które sprawia, że nasz kod praktycznie przestaje być czytelny dla ludzi. Jest on uruchamiany w momencie budowania naszej aplikacji i zaciemnia tylko ten kod, który wędruje do pliku apk. Tak więc nie wpływa on na proces rozwijania aplikacji (kod, nad którym pracujemy, pozostaje bez zmian).

Jak to wygląda w praktyce? Podczas pisania kodu naszym zmiennym, klasom oraz metodom nadaje nazwy opisowe, czyli takie, które mówią nam, jakie zadania pełni dany element. Na przykład możemy mieć klasę Kot z funkcją miaucz() oraz klasę Pies z funkcją szczekaj(). Po wykonaniu skryptu ProGuarda wszystkie nazwy zostaną zmienione na losowe. Nasza klasa Kot stanie się klasą X, a funkcja miaucz funkcją z(), to samo stanie się z klasą Pies.

Po co stosować ProGuarda? Przede wszystkim zabezpiecza on nas przed inżynierią wsteczną. Jeśli ktoś będzie próbował zdekompilować naszą aplikację, to będzie musiał przebijać się przez nic nieznaczące klasy, przez co będzie mu bardzo ciężko odgadnąć sposób działania naszego programu. Dodatkową zaletą jest zmniejszenie wagi pliku apk, ponieważ nasz kod składa się z mniejszej ilości znaków, niż gdybyśmy stosowali oryginalne nazwy opisowe.

Captcha

Captchy chyba nikomu nie trzeba przedstawiać, choć jej obecność na smartfonach nie jest zbyt powszechna. Na szczęście captcha na Androidzie nie jest aż tak problematyczna, jak jej niektóre odpowiedniki (na przykład słynne kotki z rapidshare). W przypadku Androida weryfikacja w większości przypadków odbywa się bez udziału użytkownika, ponieważ skrypt Google analizuje całe nasze urządzenie. Problem pojawia się, gdy testujemy taką aplikację na emulatorze, ponieważ wtedy zawsze zostaniemy poproszeni o ręczne rozwiązywanie zadań captchy. Rozwiązanie to jest stosowane tylko w aplikacjach, dla których bardzo ważne jest, aby nie były używane przez boty.

Limit zapytań serwerowych

Captcha ma za zadanie utrudnić automatyzację pewnych czynności w naszych aplikacjach. Zazwyczaj chodzi o to, żeby ktoś nie mógł logować się na to samo konto, próbując różnych haseł w celu uzyskania nieautoryzowanego dostępu do czyjegoś konta. W tym celu możemy wykorzystać limit zapytań oraz inne mechanizmy bezpieczeństwa znajdujące się po stronie serwera. Przeważnie działa to na tej zasadzie, że jeżeli serwer wykryje podejrzaną liczbę requestów z danego konta użytkownika lub adresu IP, to blokuje dalszą możliwość połączeń. Takie zachowanie mocno ogranicza próby włamania do systemu i z powodzeniem może zastąpić captche. Kolejną zaletą jest to, że taki mechanizm jest skuteczny i jednocześnie niewidoczny dla zwykłego użytkownika. Jest to jeden z powodów, dlaczego captcha nie jest zbytnio powszechna w aplikacjach na Androida.

Ochrona kodu źródłowego

Większość firm do zarządzania kodem źródłowym używa oprogramowania GIT. Jednak firmy te nie używają ogólnodostępnych serwerów GIT-a, lecz utrzymują repozytoria GIT na swoich własnych, prywatnych serwerach. Częstą praktyką jest również to, że aby w ogóle uzyskać połączenie do takiego serwera, należy znajdować się w firmowej sieci internetowej.

Po co takie komplikacje? Chodzi o maksymalne zabezpieczenie kodu źródłowego przed dostępem osób trzecich. W przypadku używania ogólnodostępnych serwerów ktoś mógłby próbować włamać się na konto jednego z programistów i w ten sposób wykraść kod źródłowy aplikacji. Co jak wiemy, może posłużyć do wielu niecnych celów.

Pozostałe

Ciężko wymienić wszystkie rodzaje zabezpieczeń, ponieważ każda aplikacja ma inne i o części z nich nawet nie jesteśmy świadomi. Jednak warto tutaj też wspomnieć o tym, że wszystkie dane przesyłane pomiędzy aplikacją a serwerem są wysyłane przy pomocy bezpiecznego protokołu HTTPS, co praktycznie uniemożliwia przechwytywanie i modyfikowanie przesyłanych danych. Dodatkowo częstą praktyką jest szyfrowanie wszelkich danych, przechowywanych w pamięci urządzenia. Dzięki temu nawet, jeśli ktoś wykradnie nasze informacje, to nie będzie mógł ich odczytać.

Tym sposobem dotarliśmy do końca tego artykułu. Mam nadzieję, że się podobało i wyjaśniłem nieco temat. Zdaję sobie sprawę, że nie opisałem tutaj wszystkich możliwości, lecz byłoby to bardzo trudne w jednym artykule. Liczę jednak na Was — jeśli znacie jakieś powszechnie stosowane zabezpieczenia, napiszcie o tym w komentarzu.

Tradycyjnie zachęcam do zgłaszania swoich propozycji tematów, o których chcielibyście poczytać w ramach tej serii. Widzimy się już za tydzień, gdzie odpowiem wam na pytanie, czy lepiej zacząć programowanie na Androida od Javy, czy od razu od Kotlina. Do zobaczenia za tydzień!

Zapraszam również na największe w Polsce forum dla programistów Android. Jeśli macie pytania odnośnie do kariery programisty — zapraszam do działu Kariera programowanie. Zachęcam również do przejrzenia działu Praca oraz zlecenia dla programistów — być może to właśnie tam znajdziesz swoją pierwszą pracę.

Poprzednie odcinki:

  1. Typowy dzień pracy programisty
  2. Wady pracy programisty
  3. Zalety pracy programisty
  4. [FAQ] Wszystko, co powinieneś wiedzieć, jeśli interesuje Cię praca programisty
  5. Co mnie zdziwiło w programowaniu?
  6. Motywacje – w jaki sposób nie stracić zapału do programowania?
  7. Jaką firmę wybrać na początku kariery programisty?
  8. Jak wygląda rozmowa o pracę na stanowisko programisty?
  9. Jak zacząć programować?
  10. Skąd czerpać wiedzę o programowaniu?
  11. Początki programowania — jaką technologię wybrać?
  12. Cykl życia aplikacji na Androida — co to takiego?
  13. Jak tworzymy interfejs użytkownika w aplikacjach na Androida?
  14. Jak system Android oszczędza energię?
  15. Jak działają i czym są powiadomienia push w Androidzie?
  16. W jaki sposób aplikacje pobierają dane z zewnętrznych serwisów i czym jest API?
  17. Jak działają pozwolenia w systemie Android?
  18. Śledzenie użytkowników — co wiedzą o nas aplikacje?
  19. Dlaczego aplikacje na Androida zajmują coraz więcej miejsca?
  20. Frameworki crossplatform – jak stworzyć aplikację na iOS i Androida jednocześnie?
  21. Jak obsłużyć kilka języków w aplikacji na Androida?
  22. Dodatkowe funkcjonalności Androida, których nikt nie wspiera
  23. Co się dzieje podczas kompilacji aplikacji na Androida?
  24. App Bundle – jak Google rewolucjonizuje Androida?
  25. W jaki sposób testujemy aplikacje na Androida?

Motyw