Frage:
Senden eines clientseitigen Highscores sicher an einen Server
StationaryTraveller
2017-01-15 15:45:41 UTC
view on stackexchange narkive permalink

Ich erstelle eine Webanwendung, die ein einfaches Javascript-Spiel enthält. Sobald der Spieler das Spiel beendet hat, wird der Highscore an den Server gesendet und gespeichert.

Nach einer bestimmten Zeit erhält der Spieler mit dem besten Score einen Preis.

Gibt es einen Möglichkeit, den Highscore sicher zu senden und zu verhindern, dass der Kunde "falsche" Highscores sendet?

Derzeit verwenden wir:

  • Https.
  • Server-Zufallstoken vor jedem Spiel, der nach Beendigung des Spiels zusammen mit der Punktzahl gesendet wird.
Es gibt keine narrensichere Möglichkeit, dieses Problem zu lösen.Die einzige Möglichkeit besteht darin, die individuelle Punktzahl jedes Spiels auf dem Server zu verfolgen.
TLS hat hier nichts zu tun, und Sie können auf Clientseite nichts sicherstellen, wenn es * versucht *, böswillig zu sein.Sie sollten eine [Antwort zu Ihrem eigentlichen Problem] lesen (http://security.stackexchange.com/a/147047/91111).
Es gibt hier eine ähnliche Frage, die Top-Antwort enthält eine Reihe guter Vorschläge.https://stackoverflow.com/questions/73947/what-is-the-best-way-to-stop-people-hacking-the-php-based-highscore-table-of-a-f
Übrigens stellen Sie diese Frage * viel * zu spät.Wenn es erforderlich war, sollte diese Art von Sicherheit von Anfang an eingebaut und nicht später aufgepfropft werden.
OTOH, wenn der Anreiz, Ihr Spiel zu knacken (und so Highscores zu fälschen), geringer ist als die Schwierigkeit, es zu knacken, könnte Ihr Spiel gut funktionieren, einfach weil nicht genug Interesse daran besteht, die Punktzahl zu fälschen.
Sechs antworten:
grc
2017-01-15 16:54:50 UTC
view on stackexchange narkive permalink

Der Server kann den vom Client empfangenen Daten nicht vollständig vertrauen, daher ist die Überprüfung von Highscores schwierig.

Hier einige Optionen:

  1. Verschleiern Sie den clientseitigen Code und den Datenverkehr zum Server. Dies ist die einfachste Option - es wird weiterhin möglich sein zu betrügen, aber wahrscheinlich wird es niemanden wert sein.

  2. Senden Sie eine vollständige oder teilweise Wiederholung des Spiels an den Server zur Validierung. Die Züge des Spielers können auf dem Server ausgeführt werden, um die legitime Punktzahl zu ermitteln. Dies funktioniert für einige Spiele und nicht für andere.

  3. Verschieben Sie die Spielelogik und Validierung auf den Server. Der Client leitet einfach jede Bewegung an den Server weiter, wo sie validiert und der Spielstatus aktualisiert wird.

  4. ol>

    Es kommt darauf an, wie Ihr Spiel funktioniert und wie wahrscheinlich es ist, dass Personen wird betrügen, und wie sehr es dich interessiert, wenn sie es tun.

# 3 ist der einzig richtige Weg, dies zu tun
@theonlygusti Vielleicht verstehe ich den Punkt falsch, aber Sie müssen die Spielelogik nicht verschieben - Sie müssen sie nur auf dem Server replizieren.Wenn Sie nur alle Eingaben des Spielers senden, kann der Server diese wiedergeben und die Punktzahl überprüfen.Dann müssen Sie sich nur noch um 'TASbot'-Spieler kümmern :).Ein Beispiel für ein Spiel, das das gut kann - DROD.Da es sich um ein logisches Spiel handelt, ist es auch resistent gegen werkzeuggestützte Durchspielen.Das einzige nicht behebbare Problem ist das Sniping, bei dem sich jemand die Demo eines anderen Spielers ansieht und nach Optimierungspunkten sucht.
@Maurycy Ich habe nur gesagt, dass der einzige Weg, um sicherzugehen, dass ein Highscore gültig ist, darin besteht, das Spiel auf dem Server zu verwalten.Das Verschieben / Replizieren spielt keine Rolle
@theonlygusti Ich meine, der Punkt sagt "Verschiebe die Spiellogik" und ich hatte das Gefühl, dass es nicht ausgewählt werden muss, dass du es nur replizieren musst.Ich hätte dich wahrscheinlich im Kommentar markieren sollen, weil ich wirklich vorhatte, auf die Antwort als Ganzes zu antworten, nicht auf deinen Kommentar :)
@theonlygusti: Für viele Arten von Spielen ist 2 genauso gut wie 3.
@theonlygusti Correction, # 3 ist der einzige * narrensichere * Weg, dies zu tun (aber das ist eigentlich nicht wahr, da es nicht narrensicher ist!).Es ist nur die narrensicherste und schwierigste der angebotenen Optionen.
@theonlygusti, für deterministische Spiele (denken Sie an Tetris), # 2 funktioniert, solange es Ihnen nichts ausmacht, AIs Highscore-Rekorde zu gewähren.
@Mark # 2 hat auch den Nachteil, dass ein Kunde basierend auf zukünftigem Wissen optimieren kann.Z.B.Wenn Sie in Tetris alle Teile kennen, die Sie erhalten, können Sie eine bessere Strategie finden, als wenn Sie nur ein Teil erhalten, es irgendwo platzieren und dann das nächste erhalten.
# 1 ist mit einem Javascript-Spiel nutzlos, da es viel einfacher ist, lesbaren Code neu zu generieren als mit jeder anderen Sprache.
Philipp
2017-01-15 16:54:58 UTC
view on stackexchange narkive permalink

Wenn Ihr Angreifer ein Man-in-the-Middle-Angreifer auf der Netzwerkebene wäre, würde https ausreichen. Leider ist Ihr Angreifer der Client, daher ist dies ziemlich sinnlos.

Regel Nummer eins der Cheat-Proofing-Spiele: Vertrauen Sie dem Client niemals! Der Client befindet sich in den Händen des Feindes.

Javascript-Spiele werden im Webbrowser des Benutzers ausgeführt. Wie Sie als Webentwickler sicherlich wissen, verfügt heutzutage jeder Webbrowser über einen integrierten Debugger, mit dem alle Variablen angezeigt und geändert werden können, während eine Anwendung ausgeführt wird. Der Benutzer kann den Debugger einfach verwenden, um seine Punktzahl zu ändern, bevor sie gesendet wird. Sie können nichts dagegen tun. Bei browserbasierten Spielen können Sie nicht einmal ein Anti-Cheat-Tool eines Drittanbieters darauf anwenden (das von zweifelhaftem Wert ist und ohnehin ethisch bedenklich ist).

Die einzige Gegenmaßnahme besteht darin, alle Spielmechaniken zu implementieren, die es wert sind, manipuliert zu werden auf dem Server. Der Client sollte nichts anderes tun, als die Befehle des Benutzers an den Server weiterzuleiten und das Gameplay anhand der Nachrichten des Servers zu visualisieren. Das eigentliche Gameplay sollte auf dem Server stattfinden, auf dem es für die Betrüger nicht erreichbar ist.

Ja, dies bedeutet, dass Sie die Softwarearchitektur Ihres Spiels von Grund auf neu gestalten müssen. Dies bedeutet auch, dass Sie einen Vorhersage- und Interpolationscode hinzufügen müssen, um die Netzwerkverzögerung weniger sichtbar zu machen. Dies bedeutet auch, dass Sie eine weitaus bessere Serverhardware und eine bessere Internetverbindung für Ihre Server benötigen. Wenn Sie jedoch ein betrügerfreies Online-Spiel möchten, ist dies die einzige Option.

Es gibt das übliche ** Vertrauen, aber überprüfen Sie ** die Antwort - siehe Option 2 in der Antwort von grc.
@MSalters Ist nicht ** Vertrauen, sondern Verifizierung ** ein Oxymoron?Sie vertrauen dem Client nicht, weshalb Sie seine Antwort überprüfen.Wenn Sie dem Client vertraut haben, warum müssen Sie ihn überprüfen?
@Tom "Vertrauen, aber verifizieren" ist eine gebräuchliche Phrase, die aus einem russischen Sprichwort stammt (siehe [Wikipedia] (https://en.wikipedia.org/wiki/Trust,_but_verify)).Und ja, es ist oxymoronisch, aber Sie können es auch als "unschuldig, es sei denn, es wurde als schuldig erwiesen" lesen.Oder apropos, wenn Wikipedia davon ausgeht, dass Benutzer beim Bearbeiten nach Treu und Glauben handeln (es ist nur ein Wiki, weil es nicht gesperrt ist), sie aber dennoch Referenzen zitieren müssen.
Lie Ryan
2017-01-15 22:29:01 UTC
view on stackexchange narkive permalink

Um eine sichere Spiel-Highscore zu erzielen, benötigen Sie einen " Arbeitsnachweis" oder besser gesagt einen Spielnachweis.

Ein Arbeitsnachweis / Spielen sind alle Daten, die vor dem Beenden des Spiels schwer zu berechnen sind, aber nach Beendigung des Spiels leicht zu berechnen sind und vom Server leicht überprüft werden können. Zum Beispiel ist für ein Sudoku-Spiel ein Arbeitsnachweis die Lösung für das Rätsel.

Leider gibt es in vielen Spielen keine generische Möglichkeit, ein geeignetes Proof-of-Play-System zu integrieren. Es ist nicht immer möglich, einen Proof of Play zu integrieren, ohne das Gameplay zu optimieren oder zu überarbeiten oder den Umfang der Bestenliste auf Elemente zu beschränken, bei denen Sie einen ausreichend sicheren Proof of Play einfügen können.

Proof of Play für a Das Spiel beginnt damit, dass der Server den Startwert für das RNG des Spiels ausgibt. Der Kunde muss dann einen Spielnachweis finden, der dem Samen entspricht, den der Spieler ausgegeben hat. In vielen Spielen kann ein Proof of Play erstellt werden, indem die Lösung des Spiels mit der Highscore-Übermittlung an den Server gesendet wird. In anderen Spielen kann es je nach Spiel und Proof of erforderlich sein, die gesamte Spielsitzung in verschiedenen Detailebenen aufzuzeichnen Spiel, das Sie verwenden.

Ein Spielnachweis muss wiederholungssicher sein (ein Spieler sollte nicht in der Lage sein, das fertige Spiel eines anderen Spielers zu verwenden, um die Berechnung seines eigenen Spielnachweises zu vereinfachen). Dies beschränkt den Spielnachweis auf Spiele, bei denen es eine gewisse Zufälligkeit gibt, dass Spieler den Spielnachweis eines anderen Spielers nicht einfach wiederverwenden können, sondern auch nicht zu viel nicht deterministisches Verhalten zeigen können, bis eine Überprüfung des Spiels unmöglich wird.

Beweis Das Spiel ist ebenfalls begrenzt. In einem Sudoku-Spiel ist es beispielsweise nicht möglich zu beweisen, wie viel Zeit der Spieler benötigt, um das Rätsel zu lösen. Der Spielnachweis kann auch nicht immer zwischen dem Spiel unterscheiden, das der Spieler selbst gespielt hat, und dem Spieler, der ein Skript geschrieben hat, das das Spiel für ihn gespielt hat.

Ein Ansatz, um ein "Plagiat" von Lösungen zu verhindern, besteht darin, den Namen des Spielers vor Spielbeginn anzugeben und den Zufallszahlen-Seed entsprechend diesem Namen zu hashen.und lassen Sie das Spiel den ungehackten Samen zusammen mit dem Namen und der Lösung melden.
Die Zeit ist leicht zu verfolgen, da wir hier eine Serverseite haben.Dies ist der Betrag zwischen der Erstellung des Puzzles und der Übermittlung des Ergebnisses.
CR Drost
2017-01-16 00:15:32 UTC
view on stackexchange narkive permalink

Ich wollte nur erwähnen, dass es eine Art Lösung für dieses Problem gibt, aber es ist wahrscheinlich nicht für Sie verfügbar. Die Lösung heißt "homomorphe Verschlüsselung" und ermöglicht es einem Client, eine bekannte Berechnung durchzuführen, ohne genau zu wissen, mit welchen Werten er berechnet, und einem Server, die Struktur des berechneten Werts zu überprüfen, um zu beweisen, dass der Client dies nicht getan hat Senden Sie eine zufällige Zeichenfolge zurück, bauen Sie sie jedoch tatsächlich aus den verschiedenen angegebenen Werten auf.

Das Problem ist, dass es entweder langsam oder unvollständig ist, wobei "unvollständig" bedeutet, dass "nicht alle logischen Grundelemente enthalten sind". Sehr oft handelt es sich um ein Teilsystem, das einige Verschlüsselungs- und Entschlüsselungsoperationen E (), D () sowie einige komplizierte Operationen zulässt, so dass

D (E (A) ⊕ E (B)) = A + B,

oder dergleichen.

Mal sehen, wie dies das Problem für einige Spiele löst. Stellen Sie sich ein Spiel vom Typ "Licht aus" vor, bei dem Sie auf die N -Hexfelder eines sechseckigen Gitters drücken und jedes sowohl seinen Status als auch den Status der umliegenden Felder umschaltet. Dies ist eine kommutative Algebra für diese "Pressen", und daher gibt es in einer gegebenen Lösung nicht mehr als N Pressen insgesamt, und jedes Hex hängt nur vom Anfangszustand plus den Pressen seines eigenen Hex plus den 6 Hexen um ihn herum ab.

Da unser homomorphes Verschlüsselungsschema nur + und nicht XOR zulässt, geben wir jedem Hex einen 3-Bit-Zähler für die Häufigkeit, mit der es gespiegelt wurde. (Die Client-Software verkleinert jeden doppelten Druck eines Hex automatisch auf nur einen Druck.) Die tatsächlichen Flip-Aktionen sind daher Bitvektoren, die wie folgt aussehen:

  001 001 000 000 000 001 001 001 000 001 001 000 000 ... 000 00000000 00000001  

Mit anderen Worten, sie haben 1s in jedem dieser 3-Bit-Felder, die sie umdrehen, plus eine 1 in einem 16-Bit-Zähler.

Wir verschlüsseln alle diese Werte mit einem homomorphen Verschlüsselungsschema, senden sie jeweils an den Client, und der Client sendet uns einen verschlüsselten Wert zurück, der aus diesen verschlüsselten Werten berechnet wurde, die wir zurückgesendet haben. Wir entschlüsseln dann diesen und UND den entschlüsselten Wert mit der Bitfolge

  001 001 001 001 ... 001 11111111 00000000  

und vergleichen ihn mit dem ursprünglichen Spiel -Zustand mit 0 für diese 8 Zählerbits.

Wenn sie uns einen zufälligen Wert senden, beträgt ihre Chance, dass wir ihn akzeptieren, 2 - (N + 8) sup> und daher ihre Die einzige Möglichkeit, die Tests zu bestehen, besteht darin, die von uns angegebenen Werte in einer zulässigen Kombination zu verwenden. Sie haben Zugriff auf einige Bewegungen, die wir aufgrund von Ganzzahlüberläufen nicht direkt zulassen, aber wir können die Felder immer breiter als 3 Bit machen, um diese für den Zähler rechts teurer zu machen. Aber wir haben nie ihre einzelnen Tastendrücke übertragen, geschweige denn die Geschichte wiedergegeben: Wir haben einen Vektor akzeptiert, der besagt: "So habe ich das Gitter umgedreht", was die "super-unsichere Sache" ist, vor der Sie alle warnen, aber wir haben es so gemacht, dass sie die Dinge, um die wir uns Sorgen machen, nicht tun können, ohne auf einen geheimen Schlüssel zuzugreifen.

Stattdessen sehen Sie solche Dinge bei kryptografischen Abstimmungen, bei denen Sie die Gewissheit haben möchten, dass eine Abstimmungsmaschine gibt Alice nicht spontan 1000 Stimmen.

Ich verstehe nicht, warum die Verschlüsselung hier hilfreich ist.Der einzige Weg, um sicherzustellen, dass der Kunde das Rätsel tatsächlich gelöst hat, besteht darin, den von ihm geleisteten "Arbeitsnachweis" beizufügen.Welchen Unterschied macht es, wenn der Arbeitsnachweis nicht verschlüsselt wurde?
@AgnishomChattopadhyay Können Sie sich eine Situation vorstellen, in der der Arbeitsnachweis einer Lösung S wesentlich länger ist als S selbst?Dank homomorpher Verschlüsselung müssen Sie das grundsätzlich nicht.
OscarAkaElvis
2017-01-15 16:04:08 UTC
view on stackexchange narkive permalink

Alles auf der Client-Seite kann gefälscht werden. Die Antwort lautet also nein.

BEARBEITEN Ich habe den Sicherheitsmechanismus entfernt, den ich hier geschrieben habe, weil er nur legitime Sitzungen gewährleistet ... aber gefälschte Ergebnisse können über legitime Sitzungen gesendet werden. Danke @Luke Park

Ich habe Ihren zweiten Absatz nicht verstanden.Nehmen wir an, ich behalte das 'zufällige' Token auf der Serverseite.Wie kann ich es validieren, wenn der Kunde eine Punktzahl sendet? Und im dritten Absatz: Was meinen Sie mit dem sicheren Senden eines anfänglichen zufälligen Tokens?
Wenn Sie es auf der Serverseite senden, bedeutet dies, dass Sie es, wenn Sie beispielsweise PHP verwenden, mit PHP im Backend senden müssen, nicht mit js.Ich denke, die Clients können nichts schnüffeln und wenn Sie https verwenden, wie Sie sagten, ist das genug.Um dies zu validieren, müssen Sie das erste Token (in der Datenbank in der Sitzung oder wo auch immer) auf dem Score-Server empfangen und speichern. Nachdem Sie das Token des Clients erhalten haben (das gefälscht werden könnte), müssen Sie es mit dem gesendeten ersten Token vergleichen (das gesichert ist)keine Möglichkeit, es auszutricksen.
Alles, was auf der Kundenseite vorkommt, kann gefälscht werden, das haben Sie selbst gesagt.Der Rest Ihrer Antwort ist daher nicht erforderlich.
@Luke Park fragte er: "Gibt es eine Möglichkeit, den Highscore sicher zu senden und zu verhindern, dass der Client" falsche "Highscores sendet?" Also versuche ich, den gesamten Prozess zu erklären
Es gibt keinen vollständigen Prozess.Sie können es nicht verhindern.Alles, was der legitime Kunde tut, kann von einem illegitimen Kunden gefälscht werden.
Sie liegen falsch.Der Punkt ist, dass der Server ein erstes Token für das Spiel erstellen kann, das im Backend an den Score-Server gesendet wird.Dieses Token ist SICHER.Nach den Spielen kann das Client-Token gefälscht werden. Der Sicherheitsmechanismus ist jedoch, dass das vom Client gesendete Token mit dem sicheren Token übereinstimmen muss, das zuerst beim Erstellen des Spiels gesendet wurde.
Aber der Client ist immer noch derjenige, der seine Punktzahl an den Server sendet, oder?Mit dem Token?
Lassen Sie uns [diese Diskussion im Chat fortsetzen] (http://chat.stackexchange.com/rooms/51820/discussion-between-oscarakaelvis-and-luke-park).
Nach einer Weile, in der ich tiefer darüber nachgedacht habe, denke ich, dass Sie Recht haben, Luke Park, sorry.Ich habe meine Antwort bearbeitet.
Ben Harrison
2017-01-18 22:09:42 UTC
view on stackexchange narkive permalink

Meine Empfehlung ist eher eine Technik zur Verschleierung und könnte für viele Benutzer möglicherweise eine frustrierende Hürde sein. Fortgeschrittene oder entschlossene Benutzer können Ihren Quellcode dennoch analysieren, um die Ergebnisse zu reproduzieren.

Verwenden Sie ein Tool wie Hashids, um einen Hash der Punktzahl zu erstellen, und senden Sie diesen in Ihrer Serveranforderung zusammen mit der Klartext-Partitur. Der Zeichenfolgenwert der Benutzer-ID kann das Salt sein, das zum Codieren eines Hashids der Punktzahl verwendet wird, wodurch der Hash unbrauchbar wird, wenn er gemeinsam genutzt wird. Auf der Serverseite können Sie diesen Hash dekodieren und das Ergebnis mit der gesendeten Klartextbewertung vergleichen, um sicherzustellen, dass sie wie erwartet übereinstimmen.

Ich wollte darauf hinweisen, dass Hashids nur ein Werkzeug sind, das verwendet werden kann.Eine Einschränkung bei dieser speziellen Bibliothek besteht darin, dass sie keine negativen Zahlen unterstützt (vorausgesetzt, Ihr Spiel benötigt sie möglicherweise).
Es ist nur wenig besser als das Senden eines einfachen Textes, da der Benutzer seine ID kennt und sie genau wie der Server dekodieren kann.


Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...