0

I am working on a round based web game where only one client/player at a time can perform an action. Throughout the game every player will have a websocket connection to the server. The client will send simple JSON messages like

{
    "action":"kick_in_the_face"
}

My requirements are these.

  • Nobody (player,attacker,man-in-the-middle) must be able to fake another players actions.
  • Ideally it works without the users username/password.
  • Ideally it works for unregistered users.

Some Ideas I had so far.

Method 1: Let the server send a hard to guess hash only to the authorized player and let the client send it back in the message like this

{
    "hash":"c99dd3c7c0bb5ed272c3683b1946a95d22a0abfe57284b4ba33592e478e64269"
    "action":"kick_in_the_face"
}

So if the server gets a message with the correct hash it must have been an action from the authorized player. A new hash will be computed for every message.

Method 2: I thought method 1 will be not secure enough. There is still a chance another player might guess the hash. So I thought I could implement it this way

  • At game start server and client will agree on a secure key (like in Diffie-Hellman key exchange)
  • Server creates hash and encrypts it using for example AES and the key and will send it only to the authorized client.
  • Authorized client will decrypt the hash, add the action, encrypt the JSON message and send to server.
  • Server will decrypt the message and check the hash with the original hash it send.

    Although I am not sure if method 2 is actually more secure than method 1 and will prevent wild guessing. Plus I will feel uncomfortable implementing a method to securely exchange keys.

Method 3: Ignore all of that and let the server track the authorized websocket connection. The server will then track the websocket connection of the currently authorized player and ignore messages from all other connections. Is this safe against man in the middle attacks or other attacks? Is it guaranteed that the websocket connection is not hijacked? How would I protect against that?

What method is most secure? Is there another method I should consider? Is this safe against man in the middle attacks or other attacks?

1

Use Method 3 and make sure to use TLS (WSS protocol).

If one user = one websocket connection, this is enough.

If you want to handle reconnects or want to authenticate some users, generate a random id for each user and transmit this using https. The websocket client sends the id on connect to identify itself.

TLS protects against man in the middle attacks for HTTPS and WSS.

  • Thanks for the answer. I like the idea with the random id to allow reconnects or as a way to authenticate. – Surprised Coconut Nov 14 '18 at 15:17
  • 1
    you can pass that random id along the querystring of the websocket url to avoid an additional trip. – dandavis Nov 14 '18 at 17:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.