Skocz do zawartości
globox99

Zabezpiecznie zapytań Volley Android

    Rekomendowane odpowiedzi

    Witam, piszę aplikację w której używam Volley do pobierania danych przy użyci zapytań POST (Jeśli źle to interpretuję to przepraszam)

    Posiadam własny serwer WWW do którego wysyłane są zapytania a w nich zmienne POST, wówczas przy odpowiednich parametrach otrzymuję zwrot w postaci JSON.

    Przykład:

       1. Wysłanie zapytania volley z parametrami -> login, hasło, punkty

       2. Server odbiera dane i sprawdza czy login i hasło są poprawne

           a ) dane są poprawne i server nadaje PUNKTY graczowi

           b) dane są niepoprawne i server odrzuca połączenie

      3. Server zwraca JSON a Aplikacja go odbiera i wyświetla graczowi odpowiednie info

     

    Moje pytanie brzmi.. Jak mogę zabezpieczyć wysyłanie zapytań do mojego pliku PHP na serwerze przez kogoś innego niż moja aplikacja?

    Aktualnie widzę to tak, że jeśli ktoś ogarnięty zdekompiluje aplikacje i sprawdzi jakie parametry oraz na jaki link na serverze są wysyłane to może nadać sobie nieskończoną ilość punktów.

    (Owszem zrobi to jedynie na koncie do którego zna hasło i login ale to wciąż problem...)

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Spotkałeś się z trudnym tematem. Samo zabezpieczenie endpointów (linków do których wysyłasz zapytania POST) poprzez https, oauth, jakieś tokeny generowane na podstawie informacji o urządzeniu i dołączanie ich do zapytań POST, są do obejścia, jeżeli ktoś zna hasło i login ;) 

    Moją pierwszą myślą jest przeniesienie logiki naliczania punktów na serwer. Wtedy użytkownik wysyła zapytanie do serwera: "Nalicz mi punkty" i to serwer sprawdza ile punktów danemu użytkownikowi się należy. W Twoim przypadku taka zmiana może być trudna, albo nawet niemożliwa. Wszystko zależy od tego co Twoja aplikacja robi - w jaki sposób punkty są przydzielane. 

    Możliwe też, że wystarczy wprowadzić jakiś mechanizm sprawdzający czy użytkownik mógł w tej chwili zdobyć tyle punktów, ile podał w zapytaniu POST (jaką maksymalną liczbę punktów mógł zdobyć? czy w ogóle wcześniej miał stworzoną grę i  "zdobywał punkty"? ) Jeżeli nie spełnił warunków, np. nie wykazywał wcześniej żadnej aktywności albo zdobył niesamowitą liczbę punktów, to takie requesty można odrzucać, a użytkownika banować :D 

    Jest wiele sposobów, wszystko zależy od sytuacji i od aplikacji jaka ma być zabezpieczona. Niektóre będą potrzebowały olbrzymich nakładów na bezpieczeństwo (np. aplikacje bankowe), inne o wiele mniejszych. 
    Zawsze możesz zacząć od prostych mechanizmów, a potem, w miarę potrzeb je udoskonalać.

    Jeżeli podasz więcej informacji jak działa Twoja aplikacja, to może znajdziemy sposób, w jaki najlepiej ją zabezpieczyć ;) 

    • Lubię to! 1

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    @Coders Lab

    Hej! Dzięki za odpowiedź. Myślę że nie ważne jaka byłaby aplikacja to raczej każda potrzebuje zabezpieczeń bardzo podobnych. Spodziewałem się raczej znalezienia uniwersalnego rozwiązania problemu  aby był możliwy do użycia w prosty sposób. 

     

    Moja aplikacja jest dość prosta, to gierka CookieClicker, która przyznaje punkty po zdobyciu poziomu przez gracza. Punkty są nadawane właśnie zapytaniem z parametrami POST, login hasło, punkty. Ciekawi mnie właśnie jak działają aplikacje bankowe po przecież one również muszą nie konkretne zabezpieczenia przed takim wykonywaniem zapytań.

    Nawet jeśli ogarniemy temat z przyznawaniem punktów to pozostaje wiele innych przypadków w których używam podobnych zapytań, które także nie są zabezpieczanie w żadne sposób. 

    Nie da się jakoś sprawdzić czy wysłane zapytanie pochodzi z mojej aplikacji Android? 

     

    Edytowane przez globox99

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Jeśli chodzi o banki to "słabym ogniwem" jest miejsce gdzie fizyczne pieniądze są wpłacane na konto. W placówce banku to kasjer sprawdza czy suma się zgadza i zatwierdza przypisanie pieniędzy do konta. Potem jak już robimy jakieś przelewy to wszystkie informacje są na serwerze banku. Na przykład gdy nawet wyślemy request, który jest zautoryzowany (loginem, hasłem, tokenem, itp.), o treści:
     "Przelej z mojego konta na inne konto 100 milionów"
    to prawdopodobnie dostaniemy odpowiedź:
    "Niestety na koncie nie ma wystarczających środków" (no chyba że ktoś ma takie sumy na koncie :P ale pewnie i tak, możliwość wykonania takiego przelewu jest dodatkowo zabezpieczana) 

    Ponieważ to, czy przelew może być zrealizowany, jest sprawdzane po stronie serwera.

    51 minut temu, globox99 napisał:

    Nie da się jakoś sprawdzić czy wysłane zapytanie pochodzi z mojej aplikacji Android? 

    Możesz generować Instance Id:
    https://developer.android.com/training/articles/user-data-ids#working_with_instance_ids_&_guids

    albo autoryzować się przez google:

    https://android-developers.googleblog.com/2016/01/using-google-sign-in-with-your-server.html

    Jednak to dalej nie chroni przed modyfikacją parametru w zapytaniu POST. 

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    5 godzin temu, Coders Lab napisał:

    Jednak to dalej nie chroni przed modyfikacją parametru w zapytaniu POST. 

    -.- napisałem litanię w mojej odpowiedzi ale chcąc cofnąć CTRL + Z usunęło mi wszystko ?
    Więc teraz opiszę w skrócie. Mianowicie każda gra online na Androida musi mieć połączenie z bazą danych aby tam trzymać dane postaci usera. Twórca raczej nie pozwoliłby sobie na to, żeby zapisać dane w SharedPreferences. 

    Czy jest jakaś bezpieczna alternatywa dla zapytań POST? Np. pobieranie danych bezpośrednio z bazy MySQL z hasłem ukrytym w alternatywnym wszechświecie :D ?

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    W bazie zapisywane są tylko kluczowe informacje. Takie jak właśnie dane postaci usera. A sama gra przetwarza ich o wiele więcej. Jeżeli mamy bardzo dynamiczną grę onlinę, np. jakiegoś FPSa, to gracze cały czas wysyłają dane na serwer - o swojej pozycji, akcji jaką wykonują (np. poruszanie się), czy też oddanych strzałach. Na tej podstawie serwer oblicza, gdzie się znajdują, pokazuje odpowiednie animacje innym graczom. Jeżeli gracz kogoś trafił, to nie wyśle POSTa z informacją: "trafiłem innego gracza w głowę i odebrałem mu 100 HP", tylko jego wiadomość do serwera będzie w tym stylu: "oddałem strzał z tej pozycji, z takiej broni, w tamtym kierunku i o takim czasie". To serwer sprawdzi czy na linii strzału, w odpowiednim momencie, znajdował się inny gracz. Jeżeli tak, wyliczy jak mocno on oberwał i wyśle taką informacje do reszty graczy. W tym przypadku komunikacja nie dobywa się poprzez protokół TCP (na postawie którego jest HTTP, a dalej REST i zapytania POST :P ). Gry online korzystają z innych protokołów do przesyłania pakietów. Na przykład UDP, albo nawet tworzą własne implementacje. TCP może być używane tam, gdzie nie jest potrzebna szybka wymiana danych z serwerem - jeden ruch gracza jest wykonany najwyżej co parę sekund lub w turach (karcianki, szachy). Ale o tym, co będzie wynikiem tego ruchu dalej decyduje serwer. Gracz może próbować oszukiwać, zadaniem twórcy gry jest mu te próby uniemożliwić. Sprawdzane jest czy między nim a celem, do którego strzela, nie ma np. ściany, czy jego pozycja nie zmienia się zbyt szybko, a w karciankach, czy karta której użył znajdowała się w jego puli. Możliwości jest wiele, a kreatywność twórców cheatów jest nieskończona :P

    11 godzin temu, globox99 napisał:

    Czy jest jakaś bezpieczna alternatywa dla zapytań POST?

    Jeżeli POST jest szyfrowany i zabezpieczony parą: login, hasło, lub jakimś tokenem to jest bezpieczny. Bo nikt inny nie będzie wstanie podszyć się pod usera (albo będzie miał z tym duuży problem). To sam user, jeżeli posiada konto i może się do niego zalogować - czyli wykonywać zabezpieczone zapytania, stwarza zagrożenie. W Twoim przypadku może doinstalować sobie program, który automatycznie, z dużą prędkością będzie klikał w dane miejsce na ekranie. Przez co nabije niesamowitą liczbę punktów w krótkim czasie. Twoim zadaniem jest takie sytuacje wykrywać i odrzucać, a gracza karać :P 

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    @Coders Lab 
    Dzięki za tak wyczerpującą odpowiedź. Świat jest okrutny i pełen oszustów... smutno mi, że drugie tyle czasu, które poświęciłem na pisanie aplikacji muszę przeznaczyć na zabezpieczenia :(

    Posłucham Waszych rad i zrobię wszelkie operacje przyznawania po stronie servera.

    Powiedzcie mi jeszcze jak często mogę używać takiego zapytania POST? Załóżmy, że chcę przechowywać wszelkie dane gracza takie jak: ciastka, poziom, doświadczenie, punkty w mojej bazie danych.
    Ciastka zdobywa się co sekundę oraz za każde kliknięcie w ekran. Czy mogę wykonywać zapytanie POST za każdym razem gdy gracz kliknie w ekran? Nie zrobi się jakaś pętla lub nie przeciąży to serwera?
    Nie chcę trzymać ilości ciastek w SharedPref gdyż mogą one zostać zmodyfikowane. 

     

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    3 godziny temu, globox99 napisał:

    Świat jest okrutny i pełen oszustów... smutno mi, że drugie tyle czasu, które poświęciłem na pisanie aplikacji muszę przeznaczyć na zabezpieczenia

    Na pewno znajdą się ludzie, którzy z radością zagrają w Twoją grę i nie będą nawet myśleć o oszukiwaniu ;) Na początek wystarczą proste zabezpieczenia - oszustów nie będzie dużo ( ilu jest ludzi, którzy jak widzą nową apkę w google play, to od razu chcą ją shakować?  :D  ) i na początku łatwo będzie ich wykryć. Jak Twoja aplikacja będzie zdobywać popularność to będziesz poprawiał błędy i wdrażał nowe zabezpieczenia.

    3 godziny temu, globox99 napisał:

    Czy mogę wykonywać zapytanie POST za każdym razem gdy gracz kliknie w ekran? Nie zrobi się jakaś pętla lub nie przeciąży to serwera?

    To zależy :D od wydajności serwera, od tego czy user będzie mógł grać offline itd. Jedno zapytanie powinno trwać maksymalnie 200-300 milisekund i to już jak ktoś ma bardzo wolne łącze. Tutaj musisz przetestować różne rozwiązania. Możesz robić requesty zawsze co kilka sekund - niezależnie od kliknięć usera. Albo możesz najpierw pobrać z serwera informacje ile ciastek potrzeba do zdobycia nowego poziomu i dopiero wtedy, gdy ta wartość zostanie osiągnięta, wysyłać request z ilością zdobytych ciastek. Możliwości jest wiele. Musisz sam zdecydować która dla Twojej aplikacji będzie najlepsza ;)

    • Lubię to! 1

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

    Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

    Zarejestruj nowe konto

    Załóż nowe konto. To bardzo proste!

    Zarejestruj się

    Zaloguj się

    Posiadasz już konto? Zaloguj się poniżej.

    Zaloguj się

    • Ostatnio przeglądający   0 użytkowników

      Brak zarejestrowanych użytkowników przeglądających tę stronę.

    x