0
\$\begingroup\$

Scenario

The game has leaderboards for the score at the end of a level.

Assume strong self-signed SSL encryption is used when communicating between the game client and server, and a secure handshake is established for giving the game client user the authentication token for future requests. The authentication token is used so that a handshake does not have to be established upon every single request.

Question

How do you prevent the user from extracting the authentication token from memory and fabricating a fake score request to the game server?

I am assuming that if they know how to extract the token from memory then they would know how to decompile the game client; allowing them to figure out how to send requests and understand obfuscation measures.

\$\endgroup\$
1
  • \$\begingroup\$ I am assuming that if they know how to extract the token from memory then they would know how to decompile the game client; allowing them to figure out how to send requests and understand obfuscation measures. If they are able to do that then they are also able to reverse the handshake algorithm to get their own authentication token. \$\endgroup\$
    – tkausl
    Commented Oct 25, 2023 at 21:42

2 Answers 2

2
\$\begingroup\$

You cannot. Any attempt to do this will fail against a sufficiently determined adversary.

Worse, they don't even need to sniff the authentication token out of memory. They can simply hack the code in the game client that computes a score and make it produce any value they like, then allow the client's normal handshaking and reporting mechanisms deliver this tampered payload to your server, authentically signed and everything.

You can't stop this by challenging the client to compute a checksum of its own code or similar to check if it's been modified: the attacker can simply hack the code that performs the checksum so that it does it against an unmodified copy of the executable instead of itself. Or they can inject the false score value into the right spot in memory using another process.

“The client is in the hands of the enemy” — any capability you code into the client, you have gifted to every sufficiently motivated hacker or cheater who wants to exploit your game. The best you can do is keep updating frequently, hoping the time it takes hackers to exploit the new version frustrates them more than the repeated need to download and install updates (and possible bugs that come with them) frustrates your legitimate players.

The only way to protect the legitimacy of reported scores is server-side validation, where as the game is in progress the client reports data about the play, and the server uses those play traces to either compute the score itself, or validate that the reported score is consistent with the data. Even this is still vulnerable to a hacked client coaxed into reporting super-humanly optimal — but still possible — play. To frustrate that, see "how to prevent automation-type cheating"

\$\endgroup\$
2
  • \$\begingroup\$ After reading this post and following more linked and related posts the final answer seems to be that the server needs to handle everything and the client is basically there for visuals. Of course, in this scenario, the server cost goes up exponentially since now instead of a mostly offline experience the entire gameplay must be validated constantly with the server rather than the occasional request for scores. This really only leaves one option if you want to maintain minimal server costs, which is to make it as annoying/frustrating as possible for dedicated hackers to hopefully minimize it. \$\endgroup\$
    – VoidTwo
    Commented Oct 25, 2023 at 23:45
  • \$\begingroup\$ You might not have to go quite that far. For many types of game, we can do a reasonably cheap check of whether an action was valid without reproducing all the calculations needed to perform the action in the first place, and many game actions aren't critical to validate for fairness. But if you have a game with real money stakes, like gambling or play-to-earn models, then complete server authority is a necessity. \$\endgroup\$
    – DMGregory
    Commented Oct 25, 2023 at 23:57
1
\$\begingroup\$

If the code runs on a user-controlled device, a sufficiently clever and determined user will eventually be able to emulate and/or impersonate your application in every regard.

Regarding your comment here:

This really only leaves one option if you want to maintain minimal server costs, which is to make it as annoying/frustrating as possible for dedicated hackers to hopefully minimize it.

Unfortunately no matter what you do, it's really not that hard for people who know what they're doing to compromise your client.

Ultimately, if you're doing the check client-side, somewhere in your code will be a conditional that says if(passes validation) {do legitimate thing} else {do other thing}.

All they need to do is find that branch instruction and toggle (reverse) it.

(Or if you're offloading server-side, there will be a "package results for submission" method that can be patched so it builds a false payload before getting it signed).

Neither of those really require much knowledge of the codebase, nor source code/debug symbols...

It's possible with a debugger and some patience alone, but now there are tools to run multiple instances (virtually) and fuzz branches/memory values to get a desired outcome.

This is basically what all the DRM in AAA games is trying to guard against (and why it always fails... They're not trying for long-term security, they consider delaying hackers by 60 days to be a big win).

It's also why all the competitive online games always do all the processing that can impact scoring server-side... It's the only trusted environment.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .