Anti-Cheat Javascript für Browser / HTML5-Spiel


35

Ich habe vor, ein Single-Player-Action-RPG in js / html5 zu machen, und ich möchte Betrug verhindern. Ich brauche keinen 100% igen Schutz, da es kein Multiplayer-Spiel sein wird, aber ich möchte ein gewisses Maß an Schutz.

Also, welche Strategien schlagen Sie über die Minimierung und Verschleierung hinaus vor?

Ich würde mich nicht die Mühe machen, einige serverseitige Überprüfungen einfach durchzuführen, aber ich möchte nicht den Diablo 3-Pfad wählen, um alle Änderungen meines Spielstatus auf der Serverseite beizubehalten.

Da es sich um eine Art RPG handeln wird, kam mir die Idee, einen Statistikinspektor zu erstellen, der abrupte Änderungen der Werte überprüft, aber ich bin mir nicht sicher, wie konsistent und vertrauenswürdig dies sein kann.

Was ist mit Variablen und Funktionen Escopes? Wenn immer möglich, ist es sicherer, an kleineren Schneisen zu arbeiten, aber die Mühe lohnt sich?

Gibt es überhaupt eine Möglichkeit für das Javascript, seinen Text wie in einer Prüfsumme selbst zu überprüfen?

Gibt es browserspezifische Lösungen? Ich würde mich nicht die Mühe machen, es nur in den frühen Builds für Chrome einzuschränken.


Wo werden Ihre Daten gespeichert, wie werden Ihre Daten gespeichert?
DogDog

Es ist witzig, dass Sie über Diable 3 sprechen, der "Diablo 1-Weg" war genau das und vertraute dem Kunden. Führen Sie eine Google-Suche durch, wenn Sie zu jung sind, um sich zu erinnern, was aufgrund dessen passiert ist!
Valmond


Apoc, im Moment habe ich nur einen Proof of Concept und ich habe keine Art von Persistenz implementiert - aber ich plane, eine gewisse DB-Persistenz in den ersten Builds und / oder im lokalen Speicher zu implementieren, so dass Spieler nicht einfach dort weiterspielen können, wo sie gegangen sind. Ja, Valdmond, ich habe damals meinen Anteil an Diablo gespielt. Aber ich baue kein wettbewerbsfähiges Multiplayer-Spiel oder ein vollwertiges AAA. Byte56, ich bin nicht besorgt, meinen Code zu stehlen (wer würde diesen Mist überhaupt wollen?)
Billy Ninja

Leider müssen Sie den diablo 3-Pfad gehen, wenn Sie wirklich über Hacks / Cheats besorgt sind
Noob Game Developer

Antworten:


46

Die kurze Antwort ist, dass Sie es nicht tun können. Alles, was auf der Client-Seite ausgeführt wird, insbesondere von der Quelle, kann geändert werden, um Ihre Taktik trivial zu besiegen. Wenn Sie ein clientseitiges Überprüfungsprogramm einrichten, um nach plötzlichen Änderungen zu suchen, kann ein Benutzer das Überprüfungsprogramm einfach deaktivieren.

Die gute Nachricht ist, dass Einzelspieler-Spiele im Allgemeinen kaum betrogen werden. Die einzige größere Ausnahme sind Spiele mit großen "YouTube Highscore" -Communitys wie Line Rider, in denen die Spieler über YouTube miteinander konkurrieren.

Wenn Sie das anstreben oder einfach zu hartnäckig sind, um zu akzeptieren, dass die Leute im Spiel schummeln oder selbst Highscores erzielen (was eine Form des Mehrspielers ist), müssen Sie alle Berechnungen serverseitig durchführen . Ja, alles was zählt. Sie können die Berechnungs-Client-Seite nicht einmal wiederholen, um zu versuchen, dem Benutzer die Punktzahl zu geben und sie dann beim Server zu "verifizieren", da der Benutzer dann einfach die Prüfung deaktivieren und jedes System deaktivieren kann, das sicherstellt, dass Prüfungen vorhanden sind.

Ich wünschte, es gäbe eine bessere Antwort darauf, aber es gibt keine.

Trotzdem gibt es Dinge, die Sie tun können, um das Betrügen etwas zu erschweren. Sie werden niemanden davon abhalten, es ernst zu nehmen und ein Toolkit zum Schummeln freizugeben, aber es wird sie verlangsamen:

  • Minimieren und verschleiern Sie Ihren JS, was das Lesen des Codes auf jeden Fall erschwert. Sie können die Minimierung aufheben und die Verschleierung aufheben, aber Sie können niemals die richtigen Variablen- und Funktionsnamen oder Kommentare zurückerhalten.
  • Backe Werte in einer anderen Sprache ein. In diesem Fall können Sie PHP oder andere serverseitige Sprachen verwenden, um statische Setup-Variablen zu verarbeiten. Wenn die Sprungdistanz immer 2 Felder betragen soll, definieren Sie normalerweise eine Sprungdistanz für das Spielerobjekt. Tun Sie das nicht, behandeln Sie das mit PHP, damit die JS-Quelle mit 2s endet, die an einer Million Stellen über den gesamten Code verteilt sind. Dies hat den glücklichen zusätzlichen Nebeneffekt, dass Sie auch Ihren JS beschleunigen können.
  • Mit etwas Übung werden Sie mit dem Mix vertraut und können sogar Ihren JS für jeden Spieler individuell zusammenstellen. Das ist ein weiterer Weg, um Betrug zu verhindern. Wenn der Code eines jeden Spielers anders ist, ist es schwieriger, einen Cheat zu schreiben, der Teil eines Toolkits sein kann.
  • Schließlich können Sie die Quelle anhand der Identität des Spielers prüfen. Sagen Sie ihre IP-Adresse und / oder ihren Benutzernamen. Sie wissen, wie die spielerspezifische Version des JS aussehen wird, können eine Prüfsumme einbinden und verlangen, dass sie am anderen Ende gleich ist. Einfach zu deaktivieren, wie bei jedem clientseitigen JS, macht es jedoch wieder etwas schwieriger, ein Toolkit zu erstellen.

So. Wie Sie sehen, lohnt es sich wahrscheinlich nicht, diesen Weg zu gehen. Es ist schwer. Erfordert eine Menge wirklich alberner Programmierpraktiken und ist letztendlich immer noch relativ einfach zu besiegen. Sie müssen alle Berechnungen serverseitig durchführen, um Betrug zu verhindern. Oder lass los und akzeptiere, dass Betrug passieren wird.


Das Line Rider-Beispiel ist eigentlich ziemlich trivial, wenn der Benutzer die von ihm gezeichnete Karte hochlädt und die Punktzahl berechnet. Aber Spiele wie Arkaden sind fast unmöglich, die Punktzahl serverseitig ohne umfangreiche Arbeit zu berechnen.
Orlp

@nightcracker Du hast aber auch bei so etwas wie Line Rider Recht, wenn du erst nach dem Spiel prüfst, ob das Video gemacht wurde und die YouTubes bereits getäuscht wurden. Sie sollten die Karte hochladen, wenn der Benutzer auf Play geht, den Pfad berechnen, der trivial ist, und diesen dann zurücksenden. Das Spiel sollte nicht in der Lage sein, den Pfad zu berechnen. (Wenn wir darüber reden, es zu einem Cheat-Beweis zu machen, was dieses Spiel nicht ist. Es ist nur einfach genug, dass Betrug für seine Fans offensichtlich ist.)
DampeS8N

14

Ich antwortete schon eine Frage wie das hier , und es tut mir leid zu sagen , aber:

Ich würde mich nicht die Mühe machen, einige serverseitige Überprüfungen einfach durchzuführen, aber ich möchte nicht den Diablo 3-Pfad wählen, um alle Änderungen meines Spielstatus auf der Serverseite beizubehalten.

Ist das Schlimmste, was du hier sagen könntest. Wenn Sie einen "Anti-Cheat" -Motor verwenden möchten, müssen Sie dies tun. Sie können alles, was Sie möchten, clientseitig hinzufügen, um die serverseitige Arbeit zu erleichtern, aber Sie dürfen dem Client niemals vertrauen. Die gesamte Logik muss mindestens serverseitig sein. Sie können es clientseitig reproduzieren, wenn Sie möchten, aber keine clientseitige Lösung wird es tun.

Übrigens, wenn Sie die Schwachstelle Ihres Programms finden möchten, verschleiern Sie sie nicht, lassen Sie den Code von den Leuten sehen und sagen Sie "hier, Sie haben ein Problem".

Das ist gut für Sie, für Ihren Code, für Ihre Benutzer und für die Community.


3
+1 für Serverautorität, es funktioniert einfach nicht, wenn Sie versuchen, dem Client zu vertrauen ...
Valmond

Es ist gefährlich, Dinge clientseitig zu reproduzieren. Seien Sie auch damit vorsichtig, denn wenn alles clientseitig repliziert wird, kann der Benutzer schummeln, indem er die Prüfungen mit dem Server trennt. Sie können dann das Spiel spielen, ein Video aufnehmen und ein YouTube-Star werden. Dies gilt nur für Einzelspieler-Spiele, die dieses Spiel sein wird.
DampeS8N

Wenn ich über Client-Seite spreche, ist es für "Bewegungsberechnung", "Kollisionen" usw. ... Dies kann auch für ein Multiplayer-Spiel auf beiden Seiten durchgeführt werden. Die serverseitigen Berechnungen müssen immer als prioritär betrachtet werden. Dies kann jedoch hilfreich sein, wenn Serverlatenzen bestehen, um sie auch clientseitig zu verwenden. Aber für alles, was "check cheat" Logik ist, stimme ich zu, dass alles serverseitig sein sollte.
Dievardump

Yeah, I got that. But I'm doing the project as a hobby in the little free-time that I have. Doing that kind of server checking would the complexity of the project by a lot, making it nonviable. Well, I'll keep moving with the project knowing that, and if it start to get bigger and serious than I could come up with some serious server side controlling, probably with Node.js.
Billy Ninja

this is more appropriate answer to OP
Noob Game Developer

3

Well, a good place to start is to use the Object.freeze function (which will enable protection against object patching).

This "prevents new properties from being added", "prevents existing properties from being removed", "prevents existing properties, or their enumerability, configurability, or writability, from being changed"; any changes to the internal state should be done through accessors. The following example works on chrome (should work on firefox, I dont know about IE though...):

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

5
Even this will only slow a determined cheater down. If nothing else he can steal the source, host it on his own machine, and remove the freeze code, and then use his hosts file to trick his browser into thinking the new page is the old one, reconnecting it with the server.
DampeS8N

@DampeS8N Yes, I guess you're right.
fableal

Like I said in the OP, I just want some level of protection.
Billy Ninja

This won't help at all! The user can just set a debugger breakpoint in the first JS function which gets executed and enter Object.freeze = function(o) {}; in the JS console.
Philipp

2

unfortunately, you have to go the diablo 3 path, if you are really concerned about hacks/cheats. if you are not, then basic checks you must do or its strongly advised to do.

  • buy checks - If I am buying something, I should have enough gold
  • sellchecks - If I am selling something, I need to have that item in my inventory trade checks - same as sell weapon
  • equip checks - If I am equipping a weapon, do i have/own it?
  • damage checks - If I am attacking something (enemy), I can't hit more than the maximum damage my weapon could(here you should not expect the client to tell which weapon he has used because it should have been persisted earlier)
  • crafting checks - If I crafted something, do I have all ingredients/components required?

... and so on

1 point is little bit tricky is the hero's position, since you are not much worried about it you can leave it, but its better you do that too with a minimum check like one below

  • I am at place1 @ T1, I am at place2 T2, what is the minimum time it takes to travel from place1 to place2 and it matches my T2 - T1. You can have mapping of this from small to large depending on the map size. You should have list of at least major areas like, NPC - boss, NPC - enemy spawn area (not necessarily exact location)

Hope this helps, it sounds difficult but you need to learn to make real working games


Great answer! I was writing a question on how to implement server checking, just to measure roughly how hard it is to implement server checking. You see, I don't wanna waste dozens of hours implementing a MMO-like backbone and at the end of the day it's still easily cheatable just by overriding some client request parameter or something like that. Or simply overdo what was supposed to be a simply fun game -waste effort on security instead of delivering more cool features or polish things.
Billy Ninja

1

Its basically not possible. It would be so easy to work around anything you put in place to prevent cheating.

The thing is with any software you distribute people can modify it in memory easily.

Besides if they want to cheat, let them. They're just ruining the game for themselves. There's no real practical use to cheat in this situation, you'd just destroy the gameplay for yourself.


1

I had an idea for a measure you could take to prevent/reduce cheating (in addition to other answers). You could have it set up so that the client is not given all the source code at one time, rather that every time the client wants to, say, purchase a new item in the store, that the client would have to send certain information to the server, and only recieve all the information for whatever they are purchasing if the information all matches up with what it's supposed to. If it doesn't, the server blacklists their IP or something.

You could use this in conjunction with what Dampes8n said about using different source versions, that if you can figure out a way to generate a lot of different versions, so that each user would be running an entirely different source version each time, that failing the check blacklists that source version, too, that it won't ever give out the correct item info for that source version ever again.

The main reason this would be effective is that if a hacker doesn't get the hack right the first time, this would make it much harder for them to modify the hack, because every time the hack doesn't work perfectly, they have to change their IP and write the hack all over again for the new source version.


I'd be careful. The last thing you want to do is accidentally perma-ban a paying customer.
John McDonald

@JohnMcDonald True, that. Perhaps just killing that source version. That way if they accidentally trigger the trap, they just have to refresh the browser, while still making hackers recode all their hacks.
AJMansfield

0

Yes, it can't fully be done. Always have check on the server. Anything that has an impact on the game should require authorization from the server.

That is the extend to which I will repeat other answers.

However, we can do a lot more towards the end of preventing cheats than just checking on the server. Well, we might have to add some special server checks. However, be aware that client side checks are not worthless, they save bandwidth and server work when cheaters are not involved.

With that said:

  • Mitigate rough clients: Serve over HTTPS, use Cross-origin resource sharing (CORS), allow only the same origin, use subresource integrity. I suggest to implement a service worker to enforce it on all requests, which will also mean that the game won't work by simply moving it to HTTP (because without HTTPS there is no service worker, the server worker is doing the client part of CORS and the server expects CORS), and if they serve over HTTPS it won't work because the server will reject the other origin.
  • Mitigate scripting: Use authentication and require a token to do any action. Each update cycle the server should give the client a new token, and the token is consumed by doing whatever it does... doing anything requires a valid token, the token is always changing, and thus not viable to guess, and if the client sends the same token twice or sends a wrong token the server knows that something is up. For extra protection: create a Message authentication code (MAC) of the token with a secret key and add it to te cookie. Modifying the cookie will kill the session (and they need to guess the key), and modifying the token will make the MAC check fail.
  • Mitigate code modifications: Aside from subresource integrity (which modern browsers will also check in runtime), keep your variables under a limited scope (using let, self executing anonymous functions, and javascript modules). Also, not rely on the DOM (the DOM is for IO only, not storage, if you need to attach attributes wrap your DOM objects and add them to wrappers). This way, whatever you on console should not be able to reach game logic (unless you exploit some browser vulnerability). You might also consider using techniques to detect developer tools (these are specific per browser, and may not work in all cases or stop working in the future... thus, this is an arms race).
  • Ist etwas los? Hat die Sitzung unterbrochen? Treten Sie den Spieler aus dem aktuellen Spiel und fordern Sie ihn auf, sich erneut anzumelden. Stellen Sie sich ein Captcha vor ... das den Benutzer darüber informiert, dass "etwas Seltenes vor sich geht" (es war kein zufälliger Serverausfall), und ja, das ist eine Form der Schadensbegrenzung. Oh, und nicht beschlagen, um diese zu protokollieren. Sie müssen in der Lage sein, zu überprüfen, warum sie aufgetreten sind, um falsche Postives zu verhindern und um Support-Tickets zu beantworten.

Ja, das sind alles Milderungen. Wir können immer noch einen maßgeschneiderten Browser haben, der die Integrität nicht überprüft und es Ihnen ermöglicht, Variablen in lokalen Bereichen zu erreichen und damit zu experimentieren. Dann sendet der Spielcode die geänderten Daten mit dem richtigen Token abspielen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.