Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Gra w statki, AJAX i bezpieczeństwo
Forum PHP.pl > Forum > Po stronie przeglądarki
Shlizer
Witam.
Pochylam się od jakiegoś czasu nad pewnym problemem natury bezpieczeństwa aplikacji. Mam do napisania grę w statki i jeden z trybów zakłada rozgrywkę hot-seat, czyli 2 graczy na jednym komputerze. Wygląda to tak, że jeden gracz odgrywa swoją turę, pokazuje się plansza, że teraz następuje tura gracza drugiego i prośba o wpisanie jego hasła (ustawionego tylko na czas rozgrywki), gra swoją turę, pokazuje się plansza do wpisania hasła dla drugiego gracza itd. Grywalność takiego rozwiązania jest pomijalna. =p

Całość chciałbym rozwiązać, wykonując jak najmniej odświeżeń strony, czyli pytać o ruchy i trafienia serwer asynchronicznie (JSON przesyłany AJAXem). Problem mam tylko jeden - możliwość oszustwa w grze i 'podejżenie' hasła oraz układu statków gracza drugiego, poprzez monit zapytań (np. w konsoli firebuga). Czy istnieje jakiś sposób na bezpieczny (tj. niemożliwy lub znacznie utrudniony) przesył takich danych, zakładając, że gracze mają do dyspozycji tylko przeglądarkę (SSH, sniffery i takie sprawy mnie nie interesują)?

Są zatem dwa problemy:
1. Wysyłanie hasła do serwera i sprawdzanie jego poprawności - myślałem nad SHA w JS (+sól w postaci np. czasu unixowego) i wysłanie zashaszowanego hasła, ale to można łatwo sobie wyczytać z kodu i 'przełamać'.
2. Odebranie danych z serwera, zawierających pozycje statków gracza.

Jedyny pomysł jaki mam to możliwość 'wyczyszczenia' pamięci operacji połączeń asynchronicznych, tylko nie wiem, czy istnieje pewny sposób dla różnych przeglądarek (załóżmy tylko te nowoczesne + IE10 =p) albo inne podejście do problemu, czy jestem zmuszony jednak co turę refreshować zawartość strony?
markonix
Nie bardzo rozumiem problemu.

Ajax odpytuje serwer o wynik trafienia - trafiono, nie trafiono i ewentualnie informacja o tym czy zatopiono w zależności od rodzaju gry.
Shlizer
No tak. Tyle, że po odpytaniu do przeglądarki dobiera się gracz drugi - otwiera sobie firebug, sprawdza pytania AJAX i już zna hasło przeciwnika, a co gorsza - pozycję jego statków. Dlatego właśnie jestem ciekaw, czy istnieje możliwość odpytania serwera tak, aby przeglądarka 'zapomniała' jakie pytanie i odpowiedź wędrowały do strony.
Wiem też o istnieniu JSONP, ale on wciąż jest widoczny w zakładce 'sieć'...

Generalnie chodzi o to, czy można taką grę zrobić bezpiecznie bez przeładowań strony, czy jednak nie da się tego obejść.
com
powiedz mi jedno bo nie bardzo rozumiem, gdzie trzymasz te hasła w takim razie?
SmokAnalog
Czy pomysł z tymi hasłami jest Twój? Czy to ma cokolwiek na celu czy wynika z nieumiejętności rozwiązania tego sensownie?
com
SmokAnalog i to jest dobre pytanie ,a co do problemu to może no cache? tongue.gif
Shlizer
Hasła są przechowywane po stronie serwera. Są jednorazowe (wybierane przez graczy tylko na daną rozgrywkę). Wybrałem taki sposób przechowywania ich, ponieważ po stronie przeglądarki łatwo się do nich dobrać.

SmokAnalog: pomysł z hasłami to standard dla gier typu hot-seat, choć sama implementacja w grę przeglądarkową to mój wynalazek (tzn. nie widziałem takiego rozwiązania nigdzie indziej poza grami okienkowymi).
com
powiem tak przejmujesz się na zapas, wystarczy odpowiednio skonstruować skrypt, bo skoro ma być to gra turowa no to w danej turze gracz ma mieć tylko dostęp do swojej planszy, a nie kogoś innego, wiec dajesz mu tylko takie uprawnienia i po kłopocie biggrin.gif

czyli żeby było jasne co mam na myśli:

Gracz A -> logowanie -> gra -> koniec tury -> Gracz B -> logowanie (tylko na konto gracza B, A jest wyłączone z gry w tym momencie) - >gra ->koniec tury ... itd
SmokAnalog
Przepraszam, nie doczytałem, że gra ma się odbywać na jednym komputerze. W dzisiejszych czasach wydaje mi się to totalnym dinozaurem, ale sam problem jest ciekawy.

Statki mogą być umieszczane na stronie w momencie "logowania" i przychodzić razem z odpowiedzią na logowanie. Nie musisz ich przechowywać cały czas, wtedy nie będzie możliwości podejrzenia ich przez drugiego gracza w inspektorze.
Shlizer
Cytat(SmokAnalog @ 30.10.2013, 01:37:47 ) *
Przepraszam, nie doczytałem, że gra ma się odbywać na jednym komputerze. W dzisiejszych czasach wydaje mi się to totalnym dinozaurem, ale sam problem jest ciekawy.
Sama gra będzie w zamyśle będzie posiadać 3 tryby - gry z drugą osobą przez neta, grę z AI lub właśnie hot-seat, ale zgadza się - trzecia opcja sens ma raczej mały (przy grze, gdzie ruch gracza to 3 sekundy praktycznie żaden). Sam problem jednak właśnie bardzo mnie zaciekawił, bo nie tylko w takiej gierce może się przydać przecież, a zagrożenie bezpieczeństwa, gdzie wrażliwe dane są przesyłane z/do serwera AJAXem wielokrotnie w trakcie jednej sesji, do której może mieć dostęp inny użytkownik jest spore.

Cytat
Statki mogą być umieszczane na stronie w momencie "logowania" i przychodzić razem z odpowiedzią na logowanie. Nie musisz ich przechowywać cały czas, wtedy nie będzie możliwości podejrzenia ich przez drugiego gracza w inspektorze.
Przy czym samo logowanie odbywa się AJAXem i dane o planszy także są tak pozyskiwane (nie ma znaczenia, czy to będzie jedno pytanie, czy dwa - logowanie i odpytanie o pozycję własnych statków). Gdzieś te dane muszą zostać przechowane:
- trzymanie takich informacji w DOM (i np. ukrywanie CSS) łatwo wyhaczyć
- dane trzymane jako obiekt w JS także łatwo znaleźć w inspektorze
- otrzymywanie każdorazowo w trakcie wysyłania hasła do serwera i usuwanie z DOM / obiektów JS przy końcu tury ma sens, ale te dane wciąż są widoczne w zakładce 'sieć' lub 'konsola', a więc przeglądarka przechowuje ich wartości, pomimo usunięcia ich fizycznie ze strony i są one 'do wglądu'

Zdaję sobie sprawę, że problem jest nad wyrost przy takim projekcie, ale ja jestem może dziwny i gdy widzę jakąś przeszkodę staram się ją rozwiązać, nawet jeśli sam projekt sobie bez niej może poradzić, bo kiedy indziej, w innej produkcji taka wiedza może znacznie przyspieszyć prace lub zniwelować błędy.

Niedawno wpadł mi jeszcze jeden pomysł, aby szyfrować wszystkie dane (tj. hasło w trakcie wysyłania i dane o statkach przy pobieraniu), a sam plik JS ze sposobem szyfrowania zaciemnić, aby nie dało się go w łatwy sposób odczytać. Oczywiście 'dla chcącego nic trudnego', ale taka opcja to trochę pójście na łatwiznę.
Sorry, że truję dupę o taki w sumie mało spotykany problem =p
SmokAnalog
Właśnie o to chodzi, że możesz te statki usuwać i dodawać do drzewa DOM smile.gif Sam piszę aktualnie grę opartą na Ajaksie i wiem jak ważne jest zabezpieczanie drzewa oraz branie pod uwagę, że gracz może manipulować drzewem i wysyłanymi danymi jak tylko chce.

Ja to widzę tak:
Masz 3 podstawowe stany gry:
  1. Oczekiwanie na logowanie
  2. Ruch gracza 1
  3. Ruch gracza 2

Po zalogowaniu, jako odpowiedź przychodzą:
  1. Plansza własna (żeby gracz sobie mógł zobaczyć swoje szkody)
  2. Plansza przeciwnika, ale jedynie w postaci trafionych pól, bo to żadna tajemnica i gracz ma to widzieć

Po kliknięciu na pole, wysyłają się współrzędne z odpowiedzią czy trafił.

Po wylogowaniu, z drzewa znikają wszystkie statki (po prostu usuwasz elementy), zostaje tylko pole do wpisania hasła drugiego gracza. Drugi gracz się loguje i sytuacja się powtarza.

Rozumiesz ideę? W ten sposób nikt nigdy nie zobaczy tego, czego nie powinien widzieć, bo tego tam po prostu nie będzie. Ani na ekranie, ani w inspektorze, ani nigdzie indziej smile.gif
Shlizer
SmokAnalog: Rozumiem ideę i byłaby ona cacy, ale jednak te dane można łatwo sobie odczytać.
Próbuj w swojej grze po takim AJAXowym logowaniu wejść w inspektor w zakładkę Sieć / Net / Network (w zależności, czy używasz firebuga w FF, czy masz np. Chrome'a), przewiń zapytania i zjedź w dół, otwórz ostatnie z nich i je przejrzyj - masz na tacy dane, które wysłałeś żądaniem AJAX (np. hasło), dane odebrane (np. pozycje statków) i masę dodatkowych danych z czasem wykonania żądania włącznie. Dlatego właśnie, pomimo usunięcia wszystkich elementów z DOM oraz obiektów JS, informacje poufne można nadal zgarnąć. Nie zajmuje to nawet za dużo czasu.
SmokAnalog
Moja gra nie oferuje możliwości multiplayera na jednym komputerze smile.gif Nie zagłębiałem się w te zakładki. Jeśli tak jest, to masz dwa wyjścia:
  • Szyfrować dane
  • Zrezygnować z Ajaxa na rzecz gry statycznej, przeładowań


Szyfrowanie to lepszy pomysł.
Shlizer
No chyba nie będzie innego wyboru. =/
Dzięki za rady
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.