Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cookieParser.signedCookie seems to not work properly #48

Closed
TitaneBoy opened this issue Feb 1, 2019 · 5 comments
Closed

cookieParser.signedCookie seems to not work properly #48

TitaneBoy opened this issue Feb 1, 2019 · 5 comments

Comments

@TitaneBoy
Copy link

TitaneBoy commented Feb 1, 2019

Hello everyone. I'm trying to "decode" a signed cookie I receive in a websocket session. First, here is how I setup my express session with cookie-parser:

static.ts file

import * as cookieParser from 'cookie-parser';
import * as express from 'express';
import * as session from 'express-session';

const app = express();

app.use(cookieParser('foobarbaz1234567foobarbaz1234567'));
app.use(session({
  cookie: {
    httpOnly: true,
    maxAge: 600000, // 3600000 for 1 hour & 600000 for 10 minutes
    secure: process.env.VSCodeDebug && process.env.VSCodeDebug === 'true' ? false : true,
  },
  genid: () => genuuid(),
  resave: false,
  saveUninitialized: false,
  secret: 'foobarbaz1234567foobarbaz1234567',
  store: mystore,
}));

Somewhere in my code, when I receive a websocket connection, I'm able to get the signed cookie. But I want to decode it in order to have the session ID stored inside.

This is what I'm trying to do:

image

As you can see, i'm using the same secret password with "signedCookie" than in the cookieParser initialization. The result of signedCookie returns everytime the same string as the signed cookie (temp3 value in my current example). And according to your documentation:
image
it kinda says that the signature is invalid or something like that. Is it possible that I'm missing something in my approch ? In my database where the cookie is stored, I can see the decoded cookie (i.e the session ID). So I guess that something looks wrong with "signedCookie" function (or maybe with my approch).

You can see bellow what I have in my request parameter.
Also, bellow, you can see what I observe when I'm trying to user signedCookie function. The output of this function is the same as the input (signedSession). And the secret is the same as in the cookie-parser configuration.

Here is what I have in my webSocketSingleton.ts file
import * as cookieParser from 'cookie-parser';
image

Here is what I observe when using the signedCookie function

image

Here is the content of the "req" parameter

image

image

Can you help me please to resolve this issue ? Thank you in advance for your answer

@dougwilson
Copy link
Contributor

Somewhere in your code the value you are trying to unsign has been truncated. The value you're showing starts with %3A but that is not a valid signed cookie; there should be a s in front of that value (i.e. it should start with s%3A to signal it's a signed cookie.

@dougwilson
Copy link
Contributor

You can see in the last screenshots you provided, the s is there at the start of the value, so not sure where you are loosing that character in your process.

@dougwilson
Copy link
Contributor

Taking the cookie from the last screenshot (please if you could send as text, as it look a really long time to type it out correctly :) ), here is the flow of unsigning the cookie, as an example:

$ node -pe 'var cookie = "connect.sid=s%3A1bdf23c0-9c30-93df-5147-930ece4f2f2b.Mx1bO5zIKawNmWtEZshwHG7BY%2BVCikhaUvrqWsY3TRU"; var sid = require("cookie").parse(cookie)["connect.sid"]; require("cookie-parser").signedCookie(sid, "foobarbaz1234567foobarbaz1234567")'
1bdf23c0-9c30-93df-5147-930ece4f2f2b

Basically:

(1) Parse the cookie header and get connect.sid value
(2) Pass to signedCookie with signature

@TitaneBoy
Copy link
Author

Somewhere in your code the value you are trying to unsign has been truncated. The value you're showing starts with %3A but that is not a valid signed cookie; there should be a s in front of that value (i.e. it should start with s%3A to signal it's a signed cookie.

@dougwilson You're totally right.. The first screenshot is the result of my last attempt to understand why I can't decode the signed cookie.. I was trying to remove some characters at the beginning of the original string, thinking it will resolve somehow my issue. But I forgot to put back the original string when I've created this issue. But I can assure you there was an 's' character at the beginning of the string. It's a simple forgetfulness.. My bad..

But the last screenshot, like you said (sorry ..I will send next time text string with it next time :-)..I understand it can take a while to type it correctly...), is a perfect example of why it looks to not work properly.

But When I use the "cookie" package with the "cookie-parser" package, it looks to work as expected.

So thank you very much for your answer and your help. I guess the "cookie" package was what I was missing to resolve my issue.

@CaioStoduto-zz
Copy link

CaioStoduto-zz commented Oct 2, 2020

Nowadays you need to decode the cookie value using decodeURIComponent() before using any of the following functions:

  1. cookieParser.JSONCookie
  2. cookieParser.JSONCookies (decodeURIComponent for each cookie)
  3. cookieParser.signedCookie
  4. cookieParser.signedCookies (decodeURIComponent for each cookie)

Because it doesn't decode itself inside the function, now they just check if it starts with 'j:' or 's:' (before, when this issue was created, it required an encodedURI and it would check if it starts with 'j%3A', for JSONCookie, or 's%3A', for signedCookie, and then both of these functions would decode the input to continue their codes)

these prints are from the actual expressjs/cookie-parser source code
image
image

Conclusion:
You need to use decodeURIComponent() before using JSONCookie(), JSONCookies(), signedCookie() or signedCookies() otherwise it will return the input value.

Example:

var cookieParser = require('cookie-parser')
const signedCookieValue = 's%3Accc.4qKyaFIB4mq9fpZViqe1L1hiHbbGfRTZDZHhFtTvI10' // FROM res.cookie('bbbbb', 'ccc', {signed: true})

const decodedSignedCookieValue = decodeURIComponent(signedCookieValue) // RESULT  s:ccc.4qKyaFIB4mq9fpZViqe1L1hiHbbGfRTZDZHhFtTvI10

// CORRECT WAY
cookieParser.signedCookie(decodedSignedCookieValue, 'SECRET') //RESULT ccc

// INCORRECT WAY
cookieParser.signedCookie(signedCookieValue, 'SECRET') //RESULT s%3Accc.4qKyaFIB4mq9fpZViqe1L1hiHbbGfRTZDZHhFtTvI10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants