4

I would like an explanation on how the connect.sid cookies work in the Connect Node.js framework. I noticed that they are formated like,

s:hash.signature

I don't understand how the signature is used when the hash is more than capable of being used to access the session data from a memory store or redis store.

Also, I don't understand why the s: is even in the cookie; what is it's purpose.

I'm hearing that the signature is used to "sign" the hash. What exactly is meant by "sign" or "signed"? I need an explanation on this process as well.

Thanks!

Sam
  • 6,414
  • 11
  • 46
  • 61

1 Answers1

5

The signature is there so the server can verify that it generated the cookie, not some random attacker.

Only the person who knows the secret used to sign can sign it with the same value.

"s:" is there so it is easy to know it is a signed cookie, as opposed to some other format (like unsigned).

Here's a way to retrieve data from a signed cookie and fail is signature is incorrect. Only partial code extracted from actual app, but you should get the idea.

var cookie = require('cookie');
var connect = require('connect');
var secret = "same secret used to sign cookies";

socketio.set('authorization', function(data, cb) {
  if (data.headers.cookie) {
    var sessionCookie = cookie.parse(data.headers.cookie);
    var sessionID = connect.utils.parseSignedCookie(sessionCookie['connect.sid'], secret);
    // do something here with decoded value
  }
});

You need to use the "authorization" function from socket.io so you have access to the headers. That code works when using xhr-polling transport, I'm not sure this would work for websocket for example.

Pascal Belloncle
  • 11,184
  • 3
  • 56
  • 56
  • 1
    Every sid must get it's own signed signature, otherwise it wouldn't serve a purpose. But how does the middleware know the signature is valid, does it store it in the session? Also, why not just make a really long sid instead of a signature? – Sam Feb 12 '13 at 23:53
  • the secret is in the code above is the one passed to express.session() to sign cookie. The signature is a hash of the content and the secret. – Pascal Belloncle Feb 12 '13 at 23:58
  • So when the content changes, the cookie changes? – Sam Feb 12 '13 at 23:59
  • yes, indeed. But it is probably better to just include a reference to the actual data stored on your server. Like the session id for example. – Pascal Belloncle Feb 13 '13 at 00:02
  • btw, the s: is specific to cookieSession from connect, but this is a nice convention. – Pascal Belloncle Feb 13 '13 at 00:08
  • One could even use cookie-signature by tjholowaychuck to unsign the cookies – Sam Feb 13 '13 at 00:21
  • What is the purpose of signing the cookies like this? Isn't it just as secure, yet less complicated, to just have a really long session ID hash? – Sam Feb 13 '13 at 00:22
  • same code exactly https://github.com/visionmedia/node-cookie-signature/blob/master/index.js#L17 vs https://github.com/senchalabs/connect/blob/master/lib/utils.js#L147 – Pascal Belloncle Feb 13 '13 at 00:25
  • all within the spirit of the MIT license – Pascal Belloncle Feb 13 '13 at 03:31
  • @Sam Signing the cookie allows the server to keep DoS attacks from hitting backend resources, such as databases, although I don't know if this was the reason the feature was added. Cookie + signature is essentially a long sid because it too is guessable, but the sig allows the cookie to be partly assessed for validity prior to a database lookup. – Joe Lapp Jun 12 '16 at 15:53