Il s'agit d'un problème classique avec les jeux et concours sur Internet. Votre code Flash fonctionne avec les utilisateurs pour décider du score d'un jeu. Mais les utilisateurs ne sont pas fiables et le code Flash s'exécute sur l'ordinateur de l'utilisateur. Vous êtes SOL. Il n'y a rien que vous puissiez faire pour empêcher un attaquant de se forger des scores élevés:
Flash est encore plus facile à rétroconcevoir que vous ne le pensez, car les bytecodes sont bien documentés et décrivent un langage de haut niveau (Actionscript) --- lorsque vous publiez un jeu Flash, vous publiez votre code source, que vous le sais ou pas.
Les attaquants contrôlent la mémoire d'exécution de l'interpréteur Flash, afin que quiconque sait utiliser un débogueur programmable puisse à tout moment modifier n'importe quelle variable (y compris le score actuel) ou modifier le programme lui-même.
L'attaque la plus simple possible contre votre système consiste à exécuter le trafic HTTP pour le jeu via un proxy, à capturer la sauvegarde du meilleur score et à la rejouer avec un score plus élevé.
Vous pouvez essayer de bloquer cette attaque en liant chaque enregistrement de score élevé à une seule instance du jeu, par exemple en envoyant un jeton chiffré au client au démarrage du jeu, qui pourrait ressembler à:
hex-encoding( AES(secret-key-stored-only-on-server, timestamp, user-id, random-number))
(Vous pouvez également utiliser un cookie de session dans le même sens).
Le code du jeu renvoie ce jeton au serveur avec la sauvegarde du meilleur score. Mais un attaquant peut tout simplement relancer le jeu, obtenir un jeton, puis coller immédiatement ce jeton dans une sauvegarde de score élevé rejouée.
Ainsi, vous alimentez non seulement un jeton ou un cookie de session, mais également une clé de session de cryptage à score élevé. Ce sera une clé AES 128 bits, elle-même chiffrée avec une clé codée en dur dans le jeu Flash:
hex-encoding( AES(key-hardcoded-in-flash-game, random-128-bit-key))
Maintenant, avant que le jeu ne publie le meilleur score, il déchiffre la clé de session de cryptage de score élevé, ce qu'il peut faire parce que vous avez codé en dur la clé de décryptage de clé de session de cryptage élevé dans le binaire Flash. Vous chiffrez le meilleur score avec cette clé décryptée, ainsi que le hachage SHA1 du meilleur score:
hex-encoding( AES(random-128-bit-key-from-above, high-score, SHA1(high-score)))
Le code PHP sur le serveur vérifie le jeton pour s'assurer que la demande provient d'une instance de jeu valide, puis déchiffre le score élevé crypté, vérifiant que le score élevé correspond au SHA1 du score élevé (si vous sautez cette étape , le décryptage produira simplement des scores aléatoires, probablement très élevés et élevés).
Alors maintenant, l'attaquant décompile votre code Flash et trouve rapidement le code AES, qui ressort comme un pouce endolori, même si ce n'était pas le cas, il serait retrouvé en 15 minutes avec une recherche de mémoire et un traceur ("Je sais mon score pour ce jeu est 666, alors trouvons 666 en mémoire, puis attrapons toute opération qui touche cette valeur --- oh regardez, le code de cryptage du meilleur score! "). Avec la clé de session, l'attaquant n'a même pas à exécuter le code Flash; elle attrape un jeton de lancement de jeu et une clé de session et peut renvoyer un score élevé arbitraire.
Vous êtes maintenant au point où la plupart des développeurs abandonnent simplement --- donnent ou prennent quelques mois à jouer avec les attaquants en:
Brouillage des clés AES avec des opérations XOR
Remplacement des tableaux d'octets clés par des fonctions qui calculent la clé
Diffusion de faux chiffrements clés et publications de scores élevés dans tout le binaire.
C'est surtout une perte de temps. Il va sans dire que SSL ne vous aidera pas non plus; SSL ne peut pas vous protéger lorsque l'un des deux points de terminaison SSL est mauvais.
Voici quelques éléments qui peuvent réellement réduire la fraude aux scores élevés:
Exiger une connexion pour jouer au jeu, que la connexion produise un cookie de session et n'autorise pas plusieurs lancements de jeu en suspens sur la même session ou plusieurs sessions simultanées pour le même utilisateur.
Rejetez les scores élevés des sessions de jeu qui durent moins que les vrais jeux les plus courts jamais joués (pour une approche plus sophistiquée, essayez de "mettre en quarantaine" les scores élevés pour les sessions de jeu qui durent moins de 2 écarts-types en dessous de la durée moyenne du jeu). Assurez-vous de suivre la durée du jeu côté serveur.
Rejetez ou mettez en quarantaine les scores élevés des connexions qui n'ont joué qu'une ou deux fois au jeu, de sorte que les attaquants doivent produire une "trace papier" de jeu à la recherche raisonnable pour chaque connexion qu'ils créent.
"Heartbeat" marque pendant le jeu, de sorte que votre serveur voit la croissance du score sur la durée de vie d'un jeu. Rejeter les scores élevés qui ne suivent pas des courbes de score raisonnables (par exemple, passer de 0 à 999999).
État du jeu "Instantané" pendant le jeu (par exemple, quantité de munitions, position dans le niveau, etc.), que vous pourrez ensuite rapprocher des scores intermédiaires enregistrés. Vous n'avez même pas besoin d'avoir un moyen de détecter les anomalies dans ces données pour commencer; il vous suffit de le collecter, puis vous pouvez revenir en arrière et l'analyser si les choses semblent louche.
Désactivez le compte de tout utilisateur qui échoue à l'un de vos contrôles de sécurité (par exemple, en soumettant un score élevé chiffré qui échoue à la validation).
Rappelez-vous cependant que vous ne faites que dissuader la fraude des meilleurs scores ici. Vous ne pouvez rien faire pour empêcher cela. S'il y a de l'argent en jeu dans votre jeu, quelqu'un va vaincre n'importe quel système que vous inventez. L'objectif n'est pas d' arrêter cette attaque; c'est pour rendre l'attaque plus chère que de devenir vraiment bon dans le jeu et de le battre.