crak
crak

Reputation: 48

Websocket security authentication with own credentials

I need a method how I can secure my WebSockets.

Something like onConnect->checkcredentials if(credentials===false){die()}

But with own credential data send to the server. How can I realize that without tokens or cookies? If not, is there any other solution to real-time communicate securely?

Upvotes: 0

Views: 2583

Answers (1)

EMX
EMX

Reputation: 6219

I need a method how I can secure my WebSockets.

Solution : Socket Handshake Query

With this method, only clients that know the parameter and the secret will get through the handshake gateway (middleware)

[ EDIT: use the new socket.io 2.0, it has fixed an issue regarding the query ]

@ client :

io('http://216.157.91.131:8080/', { query: "s=$€CR€T" });

@ server :

var theSecret = "S€CR€T";
io.use(function(socket, next) {
  var handshakeSecret = socket.request._query['s'];
  console.log("middleware:", handshakeSecret);
  try{
   if(handshakeSecret=theSecret){next();}else{socket.disconnect();}
  }catch(e){socket.disconnect();} //prevent error - crash
});

In this case theSecret is the same for all, could be a specific check in database.

Solution : Auth or GTFO! (Kick)

You can also doom clients that connect to a disconnection (timer kick) if they dont supply correct credentials within the timeOut. Example :

const SOCKET_AUTH_TIMEOUT = 120000; //2 minutes in ms
io.on('connection', function(socket){
    //.: ALL SOCKET CONNECTIONS :.
    console.log("[+] (unauthorized) client connected : "+socket.id);
     //begin doom countdown...
    socket.doom = setTimeout(KickSocketClient.bind(null, socket.id), SOCKET_AUTH_TIMEOUT);
     //warn this client : (example)
     //@ client : 'You got '+TimeoutInMinutes+' minutes to authorize before being kicked.'
    socket.emit('auth_required', SOCKET_AUTH_TIMEOUT);
    //.: Handle Authorization :.
    socket.on('auth',function(authRequest){
     /* your logic to verify the incoming authRequest goes here, for example :*/
     if(DATABASE[authRequest.user]){ //user exists in imaginary in-memory database
      if(DATABASE[authRequest.user].password == authRequest.password){ //correct password, success!
        socket.emit('authed', DATABASE[authRequest.user]); //maybe return user data
        socket.authed = true; //set this socket client as authorized (useful for future requests)
        //now clear the timeout of d00m! (prevent the disconnection, now the client is authed)
        clearTimeout(socket.doom);
      }else{socket.emit('error','credentials');}
     }else{socket.emit('error','credentials');}
    });
    //.: Handle Disconnections :.
    socket.on('disconnect', function(){
     if(socket.authed){console.log("[+] client disconnected : "+socket.id);}
     else{console.log("[+] (unauthorized) client disconnected : "+socket.id);}
    });
    //.: Only for Authorized Clients :.
    socket.on('secret', function(){
     if(socket.authed){
        console.log("[o] client : "+socket.id+" requested the secret");
        socket.emit('return','the secret to life'); //here you go!
     }else{socket.disconnect();} // disconnect the unauthorized client
    });
});

function KickSocketClient(sid){
 if (io.sockets.connected[sid]) {
    console.log("[kick] client ("+sid+") : unauthorized status for too long"); 
    io.sockets.connected[sid].disconnect();
 }else{ console.log("<!> : [kick] client ("+sid+") not found!"); }
}

If the client doesn't auth inside the time specified in SOCKET_AUTH_TIMEOUT it will be disconnected.

I also included in the example, a small demo for a only-authorized clients (request while unauthed = disconnection)

You can also make them join specific private namespaces once authed, so that global broadcasts to all clients doesnt include the unauthed listeners.

Good luck, hope it helped.

NOTE :

is there any other solution to real-time communicate securely?

To answer this, you need to first think of the threats. There are many ways of being secure, for example, using socket.io over SSL.

The solutions I mentioned, are for avoiding unauthorized clients from staying online and accesing events/resources/etc...

Upvotes: 2

Related Questions