I'm developing a multiplayer canvas game based on socket.io and box2d physics engine. Is there a way to limit connections to my socket endpoint and only allow connections from a specific domain?

window.socket = io.connect('http://mysite:8080');

I don't want people to be able to use my end point which is currently possible. They could just use the above code and then "manipulate" the clients logic based on the emits from the servers response.

  • \$\begingroup\$ I'm not sure about what you're asking. You need to limit the use of a particular socket? Or you want to prevent connections to your server apart from your client application? \$\endgroup\$ – liggiorgio Jun 17 '16 at 10:23
  • \$\begingroup\$ Yes the idea is to prevent connections to my endpoint (server), apart from the client application in my domain ... \$\endgroup\$ – André Ferraz Jun 17 '16 at 10:45
  • 1
    \$\begingroup\$ Impossible. Host can be spoofed. \$\endgroup\$ – Yousef Amar Jun 22 '16 at 15:43
  • \$\begingroup\$ @Paraknight If thats impossible how does Agario deal with this then? \$\endgroup\$ – André Ferraz Jun 22 '16 at 15:45
  • 2
    \$\begingroup\$ Also generally with online multiplayer games, the server is authoritative and assumes the client is a cheater. The server should know what is "correct" and prevent or kick clients that don't match up. IIRC agar.io had a pretty big bot problem - that's your proof. That's where bot detection and IP bans come in play. \$\endgroup\$ – Yousef Amar Jun 22 '16 at 15:55

After a bit of a research regarding Socket.io I realised you can control the origin that is connecting to your game (The Client) using the origin option, you can read about it over here - Socket.IO server API.

if I understood you correctly you wish to control the connections and you want to accept connections only from a specific uri (correct me if i'm wrong please), now if you dig into Socket.IO code you will find the following

 var origin = request.headers.origin || request.headers.referer
  , origins = this.get('origins');


var parts = url.parse(origin);
parts.port = parts.port || 80;
var ok =
  ~origins.indexOf(parts.hostname + ':' + parts.port) ||
  ~origins.indexOf(parts.hostname + ':*') ||
  ~origins.indexOf('*:' + parts.port);

which is checking your server.js file and looking for the following line

io.set('origins', 'www.mydomain.com:3000');

this is where you want to define the allowed domains.

| improve this answer | |
  • \$\begingroup\$ Except that the origin header can very easily be spoofed by a client, so you would definitely need some kind of authentication on top of that. \$\endgroup\$ – Yousef Amar Jun 24 '16 at 11:29
  • \$\begingroup\$ theres always the option of using Tokens to make things harder for cheaters from cheating, but theres always going to be some sort of a hack to bypass any system. \$\endgroup\$ – Daniel Netzer Jun 24 '16 at 18:30

If you have access to the box you're connecting to, couldn't you add a firewall policy to only allow a specific domain? If you don't have access to the box directly, perhaps whatever hosting service you're using allows some form of firewall control for access to your endpoint? As far as I know, that's the only way to truly prevent connections.

There are other solutions you could probably draw up with a little creativity. Authentication and disconnection of users who the server discovers are cheating is one potential way of approaching this. Usually with games involving a server, you want to make sure the server controls the actual game logic so that there's no way a hacked client can cheat.

| improve this answer | |

The server receives the connect event when the client connects to the socket.io server.

At this point, you can implement a simple verification to make sure that the person connected is supposed to be using your application.

To do so, the next event the client must send is a sign in event with some credentials (a token, for example). You can then validate the token, and only if the user has been validated should the other socket.on events be allowed to properly run.

If the user doesn't verify himself, you will immediately disconnect the socket. (If you want to get fancy, grab the IP address and blacklist the user.)

I'm not sure why the restriction has to necessarily be tied to the domain--can't that be faked? If you're really focused on security, make the client provide data that only your server can possibly provide. Then validate this data and you will know that the client is legit.

| improve this answer | |

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.