lzztt / koa-session-minimal

Minimal implementation of session middleware for Koa 2
MIT License
75 stars 13 forks source link

Additional validation support #9

Closed katanacrimson closed 2 years ago

katanacrimson commented 7 years ago

Hi, I'm trying to figure out if it'll be possible to implement some additional session validation mechanisms (to help guard against session hijacking). Currently, I don't see anywhere where ctx can be obtained by the session store from koa-session-minimal; this is something that'd be necessary for my purposes.

Is there any way that this could be implemented or hooked in? Possibly an optional Promise call for stores? A new option that takes a fn that returns a promise and gets passed the ctx and session?

lzztt commented 7 years ago

Hi damianb,

Thanks for the suggestion!

Can you give me more details/examples? Theoretically, you can save anything to the ctx.session. Do you want to save a request's ctx to the ctx.session and access it in later requests? it would hit a circular when try to serialize the session object.

katanacrimson commented 7 years ago

Less about ctx itself, more about grabbing a few elements from it (origin IP, useragent, among others) and running that against the same kind of data stored within the session, and preventing use of the session object if everything doesn't match up. Currently, when using the lib, if you're able to obtain the session ID at all, you're golden - nothing really prevents you from continuing onward with a stolen session. There doesn't seem to be a reliable way to add additional validation to harden sessions against fixation or hijacking without having to wrap or modify the library itself.

While a developer can add shim code around this library to help add validation, it's very likely that additional issues are going to be encountered; one scenario that's playing out in my mind is calling regenerateId whenever a session fails to validate, which creates the pitfall of destroying the legit user's session (and creating a denial of service vector against anyone with a legit session).

In my mind - the ability to reject a specified session id (forcing the user that fails to validate for the given session onto a new session without affecting the old session) would be the ideal solution. So:

Alice is accessing website XYZ, logs in and gets SID 1111. Bob manages to obtain Alice's SID (doesn't matter how), tries to access website XYZ using Alice's SID. Website XYZ detects Bob using a different IP, let's say, and calls it invalid, forcing Bob onto a new SID (let's say 2222). Alice should still be able to continue accessing the website on SID 1111.

Kinda running through different solutions in my head as I wrote this. Hope it helps give you an idea of what I'm shooting for.

lzztt commented 7 years ago

Thanks for the explanation, damianb,

The scenario you described makes sense to me. I am thinking how to remember and validate a user's clients (devices). IP may not be very reliable. Maybe a hashed identity token saved in client's cookie can do the work. I think we can take an optional callback function to let developers decide how to hash the identity from a ctx. We validate the hashed value against the token we get from client cookie.

Any suggestions?

katanacrimson commented 7 years ago

Hmm - I think that would be ideal. Critical thing is to not affect the original session, just the offending connection.

This will require noting that session cleanup happen regularly as a gc kind of thing, but that is probably worth noting anyways since a user can just stop browsing and there'd be sessions to clean up regardless.

Outside of that, I can't think of much else. Being flexible in validation by taking a callback/callable (and advising developers to use that feature!) should be a good way forward. I imagine having the callbac/callable give a boolean back (either via callback or promise) would be solid.