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

Divorce Redis session and cookie expiration #1130

Merged
merged 1 commit into from
Mar 3, 2017
Merged

Conversation

pkarman
Copy link
Contributor

@pkarman pkarman commented Feb 22, 2017

Why: We want the cookie to expire if/when the browser is closed,
but the Redis server-side expiration to expire after the configured
number of minutes.

@amoose
Copy link
Contributor

amoose commented Feb 22, 2017

There may be a simpler solution here. @jgrevich did some digging already and if we remove the expiry of the cookie, it becomes a session cookie and is deleted when the browser is closed.

Unlike other cookies, session cookies do not have an expiration date assigned to them, which is how the browser knows to treat them as session cookies.

@monfresh
Copy link
Contributor

We discussed this very same issue during the ICAM project but it wasn't deemed serious enough to address and has some consequences to think about. I'm pasting @amoose's comment from the ICAM issue:

+1 to @jgrevich's comment; closing the browser window can trigger logout, 
but could cause undesired behavior if the user has multiple tabs open.

What about active SP sessions?

Option 1: sign user out and deactivate all Identities in ICAM. 
Existing active sessions in SPs will be disabled when their cookies expire.

Option 2: sign user out and send LogoutRequest to each active SP session to 
deactivate each Identity and SP session. 
This approach requires the ability to send async requests from the application 
directly to the SPs.

@amoose
Copy link
Contributor

amoose commented Feb 22, 2017

Yes, thank you for bringing this up, Moncef. This cookie expiry does not address session expiry in a SP but it does ensure that login.gov won't preserve a session when the browser is closed and reopened.

@pkarman
Copy link
Contributor Author

pkarman commented Feb 22, 2017

upstream PR here roidrage/redis-session-store#84

The issue is that expire_after controls both the Redis TTL and the cookie expire value.

@monfresh
Copy link
Contributor

Note that the session will only be preserved if less than 8 minutes have passed between the closing and reopening of the browser AND a new request is made. If the tab wasn't closed, re-opening the browser doesn't make a new web request. Are we saying 8 minutes is too much of a risk? Would lowering the session_timeout_in_minutes value work?

@jgrevich
Copy link
Member

@monfresh thanks for digging that up. I tested locally and by removing the expiration date does not affect multiple tabs or SP sessions. It only affects the IdP session when the browser is closed:

diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb
index 616eee95..105c6b64 100644
--- a/config/initializers/session_store.rb
+++ b/config/initializers/session_store.rb
@@ -4,7 +4,6 @@ options = {
   key: '_upaya_session',
   redis: {
     driver: :hiredis,
-    expire_after: Figaro.env.session_timeout_in_minutes.to_i.minutes,
     key_prefix: "#{Figaro.env.domain_name}:session:",
     url: Figaro.env.redis_url,
   },

It looks like we may have to do a bit more to make sure session data is wiped from redis as well.

@pkarman
Copy link
Contributor Author

pkarman commented Feb 22, 2017

@jgrevich when you remove the expire_after config, then the data doesn't get expired from Redis.

See #1130 (comment)

@pkarman
Copy link
Contributor Author

pkarman commented Feb 28, 2017

Here's how I understand the problem.

Because the Rails session cookie has an explicit expiration value, most browsers will persist the cookie until that expiration time. That means that exiting the browser (quitting) does not delete the session cookie.

The simple solution would be to not set an explicit expiration value on the cookie, so that the cookie is destroyed when the browser exists. That's straightforward.

What's problematic is that Rails session code for the Redis driver (and others) does not distinguish between the expire value for the server-side storage and the expire value for the browser-side cookie. It uses the same value for both.

So if we remove the expiration value to fix the cookie persistence, we also stop automatically expiring the session data on the server side.

This PR addresses that problem, by splitting the configuration into 2 different settings: one for the cookie expiration (expire_after the existing config name), and one for the server-side storage expiration (ttl the new config name for the server storage).

@pkarman
Copy link
Contributor Author

pkarman commented Mar 1, 2017

New PR 18F/redis-session-store#1

**Why**: We want the cookie to expire if/when the browser is closed,
but the Redis server-side expiration to expire after the configured
number of minutes.
@pkarman pkarman changed the title [WIP] Divorce Redis session and cookie expiration Divorce Redis session and cookie expiration Mar 3, 2017
Copy link
Contributor

@zachmargolis zachmargolis left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Contributor

@monfresh monfresh left a comment

Choose a reason for hiding this comment

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

lgtm

@pkarman pkarman merged commit 86fe4fa into master Mar 3, 2017
@pkarman pkarman deleted the pek-session-cookies branch March 3, 2017 22:37
amoose pushed a commit that referenced this pull request Mar 7, 2017
**Why**: We want the cookie to expire if/when the browser is closed,
but the Redis server-side expiration to expire after the configured
number of minutes.
amoose pushed a commit that referenced this pull request Mar 8, 2017
**Why**: We want the cookie to expire if/when the browser is closed,
but the Redis server-side expiration to expire after the configured
number of minutes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants