Security Practices for Verifying Requests?

Options
Greg
edited December 2013 in Photon Server
Hey everybody,

I've been developing and prototyping an MMO concept using Photon and Unity, and I have a couple questions regarding security.

Obviously not all traffic can be encrypted for performance implications, but is there a way (or need) to verify individual requests from a given client?

For example, let's say I have a particular request: MoveInventoryItem that takes two values: a byte representing the index of the item being moved and a byte representing the index of the inventory slot being moved to. How strongly can I assume that an incoming request to the server of this particular type is actually being sent by the client associated with the PeerBase receiving the request? Is there any way the incoming request could be spoofed or otherwise illegitimate in any meaningful/preventable way? I don't see how anything could be added to validate a request aside from full-blown encryption, but I just thought I'd ask anyway since I don't want to design a system with horrible obvious security flaws caused by a simple incorrect assumption.

Also, is there a strategy for authenticating cross-server communication? I was following a tutorial that used separate server instances for separate tasks, but their strategy was to assume an incoming connection on the master server was from another server if it was on port X where clients are supposed to connect on port Y. Of course, changing the client to connect on port X instead of Y caused the client-facing server to handle the request assuming it was from a server. So the tutorial didn't really prevent situations where the client connects and says "Oh, yeah I'm a login server. Go ahead and send me [encrypted] user credentials!"

Thanks for your time,
Greg

Comments

  • Hi Greg,

    there are several approaches. Each situation is different, but here are a few ideas:

    1. Each instance of a (server-side) PeerBase represents one client connection. Once a client connection is established, there is no way that another client is sending data to that instance. It is possible, however, that the client itself is tampering with the request data (e.g.: the player has sniffed the unencrypted requests and is now modifying his outgoing data). If you want to add some "lightweight" security, you could build a simple hashcode / check sum, add it to your operation data and validate it on the server-side.

    2. A good strategy for cross-server-communication is an encrypted token, for example.
    2A) For a client that connects to a login server first + to another game server afterwards:
    The first request of a client on the login server should be an Authenticate. You create a token on the server-side and encrypt it with a private key that all servers know and send the token to the client as an operation response. Whenever a client switches between servers, it needs to send the token and the next server can decrypt the token and verify that the client has already authenticated itself. The content of the token might be a simple time stamp (like: "this client is allowed to switch between servers for the next 10 minutes"), or more specific information that should be passed from server to server. The client only sends the token - it does not need to decrypt it, so you don't have the encryption overhead on (possibly small) client devices.

    2B) To identify a Login Server:
    - If all your servers are running on the same private network, you can restrict Photon to listen on an internal IP for S2S traffic only (set the IPAddress for the appropriate listener in PhotonServer.config).
    - S2S communication can be authenticated the same way as client / user traffic: use some credentials that your servers need to send whenever they establish a S2S connection, and probably add a token afterwards (see 2A).

    If the token contains the IP+port from which the connection was originally established, you can also make sure that the token is not maliciously shared between clients.

    As said before - there are several options, and I hope I could give you some ideas how to add "a little bit more" security to your clients without using full-blown encryption on every request.

    Let me know if you have further questions!