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

feat: remove session id from session data #101

Conversation

SimenB
Copy link
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

lib/session.js Show resolved Hide resolved
lib/session.js Outdated Show resolved Hide resolved
const restoredCookie = new Cookie(cookieOpts)
restoredCookie.expires = new Date(prevSession.cookie.expires)
Copy link
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
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
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
Member

Choose a reason for hiding this comment

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

Go for that!

request.sessionStore.set('aYb4uTIhdBXCfk_ylik4QN6-u26K0u0e', {
expires: Date.now() + 1000
Copy link
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
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
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
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
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!

request.sessionStore.set('Qk_XT2K7-clT-x1tVvoY6tIQ83iP72KN', {
expires: Date.now() + 1000
Copy link
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
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...

test/session.test.js Show resolved Hide resolved
@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

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
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
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

request.sessionStore.set('Qk_XT2K7-clT-x1tVvoY6tIQ83iP72KN', {
expires: Date.now() + 1000
Copy link
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...

request.sessionStore.set('aYb4uTIhdBXCfk_ylik4QN6-u26K0u0e', {
expires: Date.now() + 1000
Copy link
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.

request.sessionStore.set('aYb4uTIhdBXCfk_ylik4QN6-u26K0u0e', {
expires: Date.now() + 1000
Copy link
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!

[hash] () {
const sess = this
const str = stringify(sess, function (key, val) {
// ignore sess.cookie property
if (this === sess && key === 'cookie') {
return
// we want `touch` to affect the hash of the session
return sess.cookie.expires
Copy link
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
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