Skip to content

feat: remove session id from session data#101

Closed
SimenB wants to merge 4 commits intofastify:masterfrom
SimenB:remove-session-id-and-encrypted-session-id-from-session-data
Closed

feat: remove session id from session data#101
SimenB wants to merge 4 commits intofastify:masterfrom
SimenB:remove-session-id-and-encrypted-session-id-from-session-data

Conversation

@SimenB
Copy link
Copy Markdown
Member

@SimenB SimenB commented Jun 28, 2022

Checklist

Fixes #52
Closes #70

I'm not 100% sure about the test changes, would like a second pair of eyes

Comment thread lib/session.js
Comment thread lib/session.js Outdated
Comment thread lib/session.js
static restore (request, idGenerator, cookieOpts, secret, prevSession, sessionId) {
const restoredSession = new Session(request, idGenerator, cookieOpts, secret, prevSession, sessionId)
const restoredCookie = new Cookie(cookieOpts)
restoredCookie.expires = new Date(prevSession.cookie.expires)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't check cookie before calling restore (

if (session && session.expires && session.expires <= Date.now()) {
), only expires. So this could be a TypeError, depending on what's in the store

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what should be done about this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either works I think, but I think it's weird to look at the expiry of the cookie and not the expiry itself.

That said, express-session only looks at the cookie data, and have not hoisted expires up into its own top level thing. So we could do the same here and just get rid of the top level expires

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go for that!

Comment thread test/base.test.js
fastify.addHook('onRequest', (request, reply, done) => {
const expires = Date.now() - 1000
request.sessionStore.set('aYb4uTIhdBXCfk_ylik4QN6-u26K0u0e', {
expires: Date.now() + 1000
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this test, so this change is probably wrong

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what would you like to do about this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to dig into the test to understand what it's supposed to test.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the intent of this test was to verify that the old secret still works. The expiration should be + 1000 to make sure the cookie hasn't expired yet.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did some spelunkling. Why did this test pass earlier?

  • The session was modified
  • sessionId and encryptedSessionId were NOT in the session store
  • This meant that a new session was created to contain the modifications

Thanks to your changes, sessionid / encryptedSessionId don't have to be in the test prep. This means the existing session will be used!

Comment thread test/base.test.js
fastify.addHook('onRequest', (request, reply, done) => {
const expires = Date.now() - 1000
request.sessionStore.set('Qk_XT2K7-clT-x1tVvoY6tIQ83iP72KN', {
expires: Date.now() + 1000
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test is explicitly "if expired", not sure why expiry was set in the future?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, this test only passed because of request.session.test = {} in the handler modified the session.

I'm starting forking off your branch, rebasing and removing...

Comment thread test/session.test.js
Comment thread test/base.test.js
@SimenB SimenB force-pushed the remove-session-id-and-encrypted-session-id-from-session-data branch from bd44a82 to a371c36 Compare June 29, 2022 08:49
@SimenB SimenB force-pushed the remove-session-id-and-encrypted-session-id-from-session-data branch from a371c36 to bd4706f Compare June 29, 2022 08:50
@jsardev
Copy link
Copy Markdown

jsardev commented Jul 10, 2022

@SimenB Hey! Can I help somehow to finish this PR? I'd need this change as well 🙏

@SimenB
Copy link
Copy Markdown
Member Author

SimenB commented Jul 21, 2022

@sarneeh sure, go for it!

We tried rolling this out at work, and had to revert due to some sessions seemingly not updating correctly. Unfortunately I haven't found the time yet to dig into it, which also means this PR is on the backburner for the moment (and now I'm on vacation, so won't get to it for at least a few more weeks). However, feel free to pick this up in the meantime!

Copy link
Copy Markdown
Contributor

@rclmenezes rclmenezes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased + fixed some issues in: #114

Comment thread test/base.test.js
fastify.addHook('onRequest', (request, reply, done) => {
const expires = Date.now() - 1000
request.sessionStore.set('Qk_XT2K7-clT-x1tVvoY6tIQ83iP72KN', {
expires: Date.now() + 1000
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, this test only passed because of request.session.test = {} in the handler modified the session.

I'm starting forking off your branch, rebasing and removing...

Comment thread test/base.test.js
fastify.addHook('onRequest', (request, reply, done) => {
const expires = Date.now() - 1000
request.sessionStore.set('aYb4uTIhdBXCfk_ylik4QN6-u26K0u0e', {
expires: Date.now() + 1000
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the intent of this test was to verify that the old secret still works. The expiration should be + 1000 to make sure the cookie hasn't expired yet.

Comment thread test/base.test.js
fastify.addHook('onRequest', (request, reply, done) => {
const expires = Date.now() - 1000
request.sessionStore.set('aYb4uTIhdBXCfk_ylik4QN6-u26K0u0e', {
expires: Date.now() + 1000
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did some spelunkling. Why did this test pass earlier?

  • The session was modified
  • sessionId and encryptedSessionId were NOT in the session store
  • This meant that a new session was created to contain the modifications

Thanks to your changes, sessionid / encryptedSessionId don't have to be in the test prep. This means the existing session will be used!

Comment thread lib/session.js
if (this === sess && key === 'cookie') {
return
// we want `touch` to affect the hash of the session
return sess.cookie.expires
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be sess.cookie.expires.toISOString() or something. The Date object gets transformed into {} by stringify

e.g. str becomes something like {"cookie":{},"csrfSecret":"5iGefd13a29MxLBIMvAT5hrZ","passport":{"user":7}}

@Uzlopak
Copy link
Copy Markdown
Contributor

Uzlopak commented Aug 11, 2022

closing this in favor of #114

@Uzlopak Uzlopak closed this Aug 11, 2022
@rclmenezes rclmenezes mentioned this pull request Aug 22, 2022
4 tasks
@SimenB SimenB deleted the remove-session-id-and-encrypted-session-id-from-session-data branch August 25, 2022 08:37
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

Successfully merging this pull request may close these issues.

Exposing encryptedSessionId leaks secret to database

5 participants