JavaScript anty-cheat dla przeglądarki / gry HTML5

35

Planuję zaryzykować rpg dla jednego gracza w js / html5 i chciałbym zapobiec oszukiwaniu. Nie potrzebuję 100% ochrony, ponieważ nie będzie to gra wieloosobowa, ale chcę mieć pewien poziom ochrony.

Jakie więc strategie sugerujesz poza minimalizowaniem i zaciemnianiem?

Nie zawracałbym sobie głowy prostym sprawdzaniem po stronie serwera, ale nie chcę iść ścieżką Diablo 3, utrzymując wszystkie moje zmiany stanu gry po stronie serwera.

Ponieważ będzie to rodzaj rpg, wpadłem na pomysł stworzenia inspektora statystyk, który sprawdzałby nagłe zmiany ich wartości, ale nie jestem pewien, czy może być spójny i wiarygodny.

A co ze zmiennymi i funkcjami ucieczki? Praca na mniejszych schodach jest zawsze bezpieczniejsza, ale czy warto?

Czy w każdym razie javascript może sam sprawdzać tekst, tak jak suma kontrolna?

Czy istnieją rozwiązania specyficzne dla przeglądarki? Nie zawracałbym sobie głowy ograniczeniem go dla Chrome tylko we wczesnych wersjach.

Billy Ninja
źródło
Gdzie są zapisywane twoje dane, w jaki sposób są zapisywane?
DogDog
Zabawne, że mówisz o Diable 3, „Diablo 1 way” było właśnie tym, ufając klientowi. Wykonaj wyszukiwanie w Google, jeśli jesteś zbyt młody, aby pamiętać, co się stało z tego powodu!
Valmond
Apoc, w tej chwili mam tylko dowód koncepcji i nie wdrożyłem żadnej trwałości - ale planuję zaimplementować pewną wytrzymałość DB w pierwszych kompilacjach i / lub lokalnej pamięci, aby gracze nie mogli grać dalej od miejsca, z którego wyszli. Tak, Valdmond, grałem wtedy w Diablo. Ale nie buduję konkurencyjnej gry wieloosobowej ani w pełni oznaczonej AAA. Byte56, nie martwię się o kradzież mojego kodu (kto i tak chciałby tego gówna?)
Billy Ninja,
niestety, musisz przejść ścieżkę diablo 3, jeśli naprawdę martwisz się o hacki / kody
Noob Game Developer

Odpowiedzi:

46

Krótka odpowiedź brzmi: nie możesz tego zrobić. Wszystko, co działa po stronie klienta, szczególnie ze źródła, można zmodyfikować, aby trywialnie pokonać twoją taktykę. Jeśli umieścisz moduł sprawdzania po stronie klienta w celu wyszukiwania nagłych zmian, użytkownik może po prostu wyłączyć moduł sprawdzania.

Dobrą wiadomością jest to, że ogólnie rzecz biorąc, gry dla jednego gracza są bardzo małe. Jedynym ważnym wyjątkiem są gry z dużymi społecznościami „youtube highscore”, takimi jak Line Rider, w których gracze rywalizują ze sobą przez YouTube.

Jeśli dążysz do tego lub jesteś zbyt uparty, aby zaakceptować fakt, że ludzie mogą oszukiwać w grze lub samemu utrzymujesz wysokie wyniki (co jest formą gry wieloosobowej), musisz wykonać wszystkie obliczenia po stronie serwera . Tak, wszystko, co ważne. Nie można nawet powtórzyć obliczeń po stronie klienta, aby spróbować dać użytkownikowi wynik, a następnie „zweryfikować” go na serwerze, ponieważ użytkownik może wtedy po prostu wyłączyć sprawdzanie i wyłączyć dowolny system, który zapewnia kontrole.

Chciałbym, żeby była na to lepsza odpowiedź, ale nie ma.

To powiedziawszy, są rzeczy, które możesz zrobić, aby trochę trudniej było oszukiwać. Nie powstrzymają nikogo poważnie od zrobienia tego i wydania zestawu narzędzi do oszukiwania, ale spowolni to:

  • Zminimalizuj i zaciemnij swój JS, co absolutnie utrudni odczytanie kodu. Możesz usunąć i zminimalizować zaciemnienie, ale nigdy nie możesz odzyskać odpowiednich nazw zmiennych i funkcji ani komentarzy.
  • Piec wartości w innym języku. W takim przypadku możesz użyć PHP lub innych języków po stronie serwera do obsługi statycznych zmiennych konfiguracyjnych. Jeśli odległość skoku ma zawsze wynosić 2 spacje, zwykle określa się odległość skoku dla obiektu gracza. Nie zajmuj się tym z PHP, tak aby źródło JS skończyło się na 2s otynkowanych w całym kodzie w milionach miejsc. Ma to pozytywny efekt uboczny, ponieważ możesz przyspieszyć swój JS.
  • Po pewnym ćwiczeniu zyskasz biegłość w miksowaniu, a nawet stworzysz własne JS dla każdego gracza. Który jest innym sposobem zapobiegania oszustwom. Jeśli kod każdego gracza jest w jakiś sposób inny, trudniej jest napisać kod, który może być częścią zestawu narzędzi.
  • Na koniec możesz sprawdzić sumę źródłową na podstawie tożsamości gracza. Powiedz ich adres IP i / lub nazwę użytkownika. Wiesz, jaka będzie wersja JS dla konkretnego gracza, możesz upiec sumę kontrolną i wymagać, aby była taka sama na drugim końcu. Łatwo go wyłączyć, jak każdy JS po stronie klienta, ale jeszcze raz trudniej jest stworzyć zestaw narzędzi.

Więc. Jak widać, prawdopodobnie nie warto iść tą trasą. To jest trudne. Wymaga wielu naprawdę niemądrych praktyk kodowania i ostatecznie jest nadal stosunkowo łatwy do pokonania. Musisz wykonać wszystkie obliczenia po stronie serwera, aby zapobiec oszukiwaniu. Albo puść i zaakceptuj, że nastąpi oszustwo.

DampeS8N
źródło
Przykład liniowca jest naprawdę dość trywialny, aby zrobić po stronie serwera, pozwalając użytkownikowi przesłać mapę, którą narysował i obliczyć wynik. Ale gry takie jak arkady są prawie niemożliwe do obliczenia po stronie serwera wyników bez obszernej pracy.
orlp
@nightcracker Masz rację, jednak nawet z czymś takim jak Line Rider, jeśli sprawdzisz dopiero po zakończeniu gry, wideo zostało zrobione, a YouTubes już skopiowane. Powinieneś załadować mapę, gdy użytkownik przejdzie do gry, obliczyć ścieżkę, która jest trywialna, a następnie odesłać ją z powrotem. Gra nie powinna być w stanie obliczyć ścieżki. (Jeśli mówimy o tym, aby uczynić go odpornym na oszustwa, co nie jest tą grą. To jest po prostu tak proste, że oszustwo jest oczywiste dla jego fanów.)
DampeS8N
14

Odpowiedziałem już na takie pytanie tutaj i przykro mi to mówić, ale:

Nie zawracałbym sobie głowy prostym sprawdzaniem po stronie serwera, ale nie chcę iść ścieżką Diablo 3, utrzymując wszystkie moje zmiany stanu gry po stronie serwera.

To najgorsza rzecz, jaką mogłeś tu powiedzieć. Jeśli chcesz zrobić silnik zapobiegający oszukiwaniu, musisz to zrobić. Możesz dodać wszystko, co chcesz po stronie klienta, aby ułatwić pracę po stronie serwera, ale nigdy nie możesz ufać klientowi. Cała logika, którą masz musi być przynajmniej po stronie serwera. Możesz go odtworzyć po stronie klienta, jeśli chcesz, ale żadne rozwiązanie po stronie klienta tego nie zrobi.

A tak przy okazji, jeśli chcesz znaleźć słabość swojego programu, nie zaciemniaj go, pozwól ludziom zobaczyć twój kod i powiedzieć ci „tutaj masz problem”.

To dobrze dla ciebie, dla twojego kodu, dla twoich użytkowników i dla społeczności.

dievardump
źródło
3
+1 dla uprawnień serwera, to po prostu nie działa, jeśli próbujesz zaufać klientowi ...
Valmond,
Powielanie rzeczy po stronie klienta jest niebezpieczne. Bądź ostrożny, nawet jeśli wszystko jest replikowane po stronie klienta, użytkownik może oszukiwać, rozłączając kontrole z serwerem. Następnie mogą zagrać w grę, nagrać film i zostać gwiazdą YouTube. Dotyczy to wyłącznie gier dla jednego gracza, którymi będzie ta gra.
DampeS8N
Kiedy mówię o stronie klienta, chodzi o „obliczanie ruchów”, „kolizje” itp. Można to zrobić po obu stronach, nawet w przypadku gry wieloosobowej. Obliczenia po stronie serwera należy zawsze traktować priorytetowo, ale może to pomóc, gdy występuje opóźnienie serwera, aby mieć je również po stronie klienta. Ale dla wszystkiego, co jest logiką „cheat cheat”, zgadzam się, że wszystko powinno być po stronie serwera.
dievardump
Tak, mam to. Ale robię ten projekt jako hobby w moim wolnym czasie. Wykonanie tego rodzaju sprawdzania serwera znacznie skomplikowałoby projekt, przez co byłby nieopłacalny. Cóż, będę kontynuował pracę nad projektem, wiedząc o tym, a jeśli zacznie on być większy i poważniejszy niż mógłbym wymyślić jakieś poważne sterowanie po stronie serwera, prawdopodobnie z Node.js.
Billy Ninja,
jest to bardziej odpowiednia odpowiedź na OP
Noob Game Developer
3

Cóż, dobrym miejscem do rozpoczęcia jest użycie funkcji Object.freeze (która zapewni ochronę przed łataniem obiektów).

To „zapobiega dodawaniu nowych właściwości”, „zapobiega usuwaniu istniejących właściwości”, „uniemożliwia zmianę istniejących właściwości lub ich wyliczalność, konfigurowalność lub zapisywalność”; wszelkie zmiany stanu wewnętrznego powinny być dokonywane za pośrednictwem akcesoriów. Poniższy przykład działa na Chrome (powinien działać na Firefox, chociaż nie wiem o IE ...):

var b = {}
// Fill your object with whatever you want
b.a = "ewq"
// Freeze all changes
Object.freeze(b)
// Try to put new value. This wont throw any error, put wont work either, 
// as we shall see ...
b.b = "qwe"

// Values 
console.log(b.a); // outputs "eqw"
console.log(b.b); // outputs  undefined
bajka
źródło
5
Nawet to spowolni tylko zdecydowanego oszusta. Jeśli nic więcej nie może ukraść źródła, umieścić go na swoim komputerze i usunąć kod zatrzymania, a następnie użyć pliku hosts, aby oszukać przeglądarkę, aby pomyślała, że ​​nowa strona jest stara, ponownie łącząc ją z serwerem.
DampeS8N
@ DampeS8N Tak, myślę, że masz rację.
Fableal
Tak jak powiedziałem w PO, chcę tylko pewien poziom ochrony.
Billy Ninja,
To wcale nie pomoże! Użytkownik może po prostu ustawić punkt przerwania debuggera w pierwszej funkcji JS, która zostanie wykonana i wejść Object.freeze = function(o) {};do konsoli JS.
Philipp
2

niestety, musisz przejść ścieżkę diablo 3, jeśli naprawdę martwisz się o hacki / kody. jeśli nie, to należy wykonać podstawowe kontrole lub zdecydowanie zaleca się je wykonać.

  • kup czeki - jeśli coś kupuję, powinienem mieć wystarczającą ilość złota
  • sprawdzanie sprzedaży - jeśli coś sprzedaję, muszę mieć ten przedmiot w czekach handlowych ekwipunku - tak samo jak sprzedaż broni
  • kontrole wyposażenia - czy posiadam broń, czy mam ją / mam?
  • testy uszkodzeń - jeśli atakuję coś (wroga), nie mogę trafić więcej niż maksymalne obrażenia, jakie moja broń mogłaby (tutaj nie powinieneś oczekiwać, że klient powie, której broni użył, ponieważ powinna była zostać utrwalona wcześniej)
  • czeki rzemieślnicze - jeśli coś wytworzyłem, czy mam wszystkie wymagane składniki / składniki?

... i tak dalej

1 punkt jest nieco trudny, ponieważ pozycja bohatera jest niewielka, ponieważ nie martwisz się o to, możesz go zostawić, ale lepiej też zrobić to z minimalną wartością kontrolną, jak poniżej

  • Jestem na miejscu 1 @ T1, jestem na miejscu 2 T2, jaki jest minimalny czas podróży z miejsca 1 na miejsce 2 i pasuje do mojego T2 - T1. Możesz mieć mapowanie tego od małego do dużego, w zależności od wielkości mapy. Powinieneś mieć listę przynajmniej głównych obszarów, takich jak NPC - boss, NPC - obszar odradzania wroga (niekoniecznie dokładna lokalizacja)

Mam nadzieję, że to pomaga, brzmi to trudnie, ale musisz nauczyć się tworzyć prawdziwe gry

Twórca gry Noob
źródło
Świetna odpowiedź! Pisałem pytanie, jak zaimplementować sprawdzanie serwera, aby z grubsza zmierzyć, jak trudne jest wdrożenie sprawdzania serwera. Widzisz, nie chcę tracić dziesiątek godzin na wdrożenie szkieletu podobnego do MMO, a pod koniec dnia nadal łatwo go oszukiwać, po prostu zastępując jakiś parametr żądania klienta lub coś takiego. Lub po prostu przesadzaj z tym, co miało być po prostu zabawną grą - zużyty wysiłek na rzecz bezpieczeństwa zamiast dostarczania fajniejszych funkcji lub dopracowywania.
Billy Ninja,
1

Zasadniczo jest to niemożliwe. Byłoby tak łatwo obejść wszystko, co wprowadzisz, aby zapobiec oszustwom.

Chodzi o to, że każde oprogramowanie, które dystrybuujesz, może łatwo modyfikować je w pamięci.

Poza tym, jeśli chcą oszukiwać, pozwól im. Rujnują grę dla siebie. W tej sytuacji nie ma praktycznego zastosowania do oszukiwania, po prostu zniszczyłbyś rozgrywkę dla siebie.

tsturzl
źródło
1

Wpadłem na pomysł środka, który można podjąć, aby zapobiec / zmniejszyć oszustwo (oprócz innych odpowiedzi). Możesz ustawić go tak, aby klient nie otrzymał jednocześnie całego kodu źródłowego, zamiast tego, że za każdym razem, gdy klient chce, powiedzmy, kupić nowy produkt w sklepie, musiałby przesłać pewne informacje do serwer i odbierają wszystkie informacje dotyczące tego, co kupują, tylko jeśli wszystkie informacje są zgodne z tym, co powinny. Jeśli nie, serwer umieszcza na czarnej liście ich IP lub coś w tym rodzaju.

Możesz użyć tego w połączeniu z tym, co Dampes8n powiedział o używaniu różnych wersji źródłowych, że jeśli możesz znaleźć sposób na wygenerowanie wielu różnych wersji, tak aby każdy użytkownik za każdym razem uruchamiał zupełnie inną wersję źródłową, że to sprawdź również czarne listy tej wersji źródłowej, aby nigdy więcej nie podawała poprawnych informacji o produkcie dla tej wersji źródłowej.

Głównym powodem, dla którego byłoby to skuteczne, jest to, że jeśli haker nie uda się prawidłowo za pierwszym razem, znacznie trudniej będzie go zmodyfikować, ponieważ za każdym razem, gdy hack nie działa idealnie, musi zmień ich adres IP i ponownie napisz hack dla nowej wersji źródłowej.

AJMansfield
źródło
Byłbym ostrożny. Ostatnią rzeczą, którą chcesz zrobić, jest przypadkowe zablokowanie płatnego klienta.
John McDonald
@JohnMcDonald To prawda. Być może po prostu zabijam tę wersję źródłową. W ten sposób, jeśli przypadkowo uruchomią pułapkę, muszą tylko odświeżyć przeglądarkę, jednocześnie zmuszając hakerów do kodowania wszystkich swoich hacków.
AJMansfield
0

Tak, nie można tego w pełni zrobić. Zawsze miej czek na serwerze. Wszystko, co ma wpływ na grę, wymaga autoryzacji z serwera.

Do tego stopnia powtórzę inne odpowiedzi.

Możemy jednak zrobić znacznie więcej pod koniec zapobiegania oszustwom niż tylko sprawdzanie serwera. Cóż, być może będziemy musieli dodać specjalne kontrole serwera. Należy jednak pamiętać, że kontrole po stronie klienta nie są bezwartościowe, oszczędzają przepustowość i pracę serwera, gdy oszustowie nie są zaangażowani.

Powiedziawszy to:

  • Ograniczanie szorstkich klientów: obsługuj przez HTTPS, używaj współdzielenia zasobów między źródłami (CORS), zezwalaj tylko na to samo pochodzenie, używaj integralności podśrodków. Proponuję zaimplementować pracownika usługowego, aby wymusić go na wszystkich żądaniach, co oznacza również, że gra nie będzie działać, po prostu przenosząc go do HTTP (ponieważ bez HTTPS nie ma pracownika usługowego, pracownik serwera wykonuje część klienta CORS i serwer oczekuje CORS), a jeśli będą obsługiwać przez HTTPS, nie będzie działać, ponieważ serwer odrzuci inne źródło.
  • Ograniczanie skryptów: użyj uwierzytelnienia i do wykonania dowolnej czynności wymagany jest token. W każdym cyklu aktualizacji serwer powinien dać klientowi nowy token, a token jest zużywany przez robienie tego, co robi ... robienie czegokolwiek wymaga ważnego tokena, token zawsze się zmienia, a zatem nie można go zgadnąć, a jeśli klient wysyła ten sam token dwa razy lub wysyła zły token, serwer wie, że coś jest nie tak. Dla dodatkowej ochrony: utwórz kod uwierzytelniania wiadomości (MAC) tokena za pomocą tajnego klucza i dodaj go do pliku cookie. Modyfikacja pliku cookie zabije sesję (i muszą odgadnąć klucz), a modyfikacja tokena spowoduje niepowodzenie sprawdzania adresu MAC.
  • Ogranicz modyfikacje kodu: Oprócz integralności podśrodków (które nowoczesne przeglądarki sprawdzają również w środowisku wykonawczym), utrzymuj zmienne w ograniczonym zakresie (używając let, samodzielnie wykonujących anonimowych funkcji i modułów javascript). Ponadto nie należy polegać na modelu DOM (DOM jest przeznaczony tylko do IO, a nie do przechowywania, jeśli musisz dołączyć atrybuty, zawiń obiekty DOM i dodaj je do opakowań). W ten sposób cokolwiek na konsoli nie powinno być w stanie uzyskać dostępu do logiki gry (chyba że wykorzystasz jakąś lukę w przeglądarce). Możesz również rozważyć użycie technik wykrywania narzędzi programistycznych (są one specyficzne dla poszczególnych przeglądarek i mogą nie działać we wszystkich przypadkach lub przestać działać w przyszłości ... dlatego jest to wyścig zbrojeń).
  • Coś się dzieje? Czy sesja się zepsuła? Wyrzuć gracza z bieżącego meczu, poproś o ponowne zalogowanie. Pomyśl o captcha ..., która ma również tę zaletę, że mówi użytkownikowi, że „wiemy, że dzieje się coś rzadkiego” (nie była to przypadkowa awaria serwera) i tak, to jest forma łagodzenia. Aha, i nie zapominajcie, żeby je zalogować. Musisz być w stanie sprawdzić, dlaczego tak się stało, zarówno w celu uniknięcia fałszywych postów, jak i odpowiedzi na zgłoszenia do pomocy technicznej.

Tak, to wszystko łagodzenie. Nadal możemy mieć niestandardową przeglądarkę, która nie sprawdzi integralności i pozwoli ci sięgać po zmienne w lokalnych zakresach ... i wtedy kod gry wyśle ​​zmodyfikowane dane odpowiednim tokenem, i tam właśnie przychodzą kontrole serwera grać.

Theraot
źródło