sorcery icon indicating copy to clipboard operation
sorcery copied to clipboard

reset_session after logging in wipes out non-sorcery info from session such as csrf_token

Open olivoil opened this issue 12 years ago • 15 comments

Hi,

After a user logs in, Sorcery cleans out the session, as mentionned in issue #31, using ActiveRecord::Base#reset_session, which is useful to prevent session fixation attacks.

However, this has the side effect of wiping out other session information, such as session[:_csrf_token].

In the case of the csrf token, it would not be noted in applications using rails generated html forms, as these would call ActionController::RequestForgeryProtection#form_authenticity_token, thus regenerating session[:_csrf_token]. However, if you log in through json requests and generate forms client-side, session[:csrf_token] would not be regenerated and all subsequent requests would be invalidated, wiping out the session again.

Looking at Devise, if I'm not mistaken, they only wipe out devise related information after logging in with Devise::Controllers::Helpers#expire_session_data_after_sign_in!

def expire_session_data_after_sign_in!
  session.keys.grep(/^devise\./).each { |k| session.delete(k) }
end

If you're interested, I can work out a pull request to clean only Sorcery related info from the session, as Devise seems to be doing.

My understanding is that the session should be wiped out, but session info not related to Sorcery should be copied over to the new session. Does that seem like a good approach or am I overseeing any security concerns here?

Thanks!

olivoil avatar Apr 02 '12 19:04 olivoil

I'm just now running into the exact same issue for the exact same reason.

elijahsmith avatar Apr 02 '12 21:04 elijahsmith

I am too, I would be more then happy to help.

MikeSilvis avatar Apr 09 '12 13:04 MikeSilvis

I also need custom data stored in session to persist after login.

jrhorn424 avatar Apr 16 '12 23:04 jrhorn424

the only way I found to do this, was in your controller set your original session = to a local var, login, and before the redirect reinstate the session.

MikeSilvis avatar Apr 17 '12 19:04 MikeSilvis

@MikeSilvis You can also use after_login and after_logout hooks provided by Sorcery. They happen after the reset_session is called, and take the user object and an array of his credentials as arguments.

The gist would look something like:

# in initializers/sorcery.rb
config.after_login << :regenerate_session_info

# in application_controller.rb
private
def regenerate_session_info(user, credentials)
  form_authenticity_token
  session[:my_user_config] = user.my_user_config
end

Hope it does helps until we pull-request a more elegant solution.

olivoil avatar Apr 17 '12 21:04 olivoil

that's very helpful. Thank you

MikeSilvis avatar Apr 18 '12 00:04 MikeSilvis

+1 same issue here

weppos avatar Jun 11 '12 12:06 weppos

Anyone is working or have input on this?

ph avatar Sep 20 '12 17:09 ph

Need help on this please! I am running into the same issue. Sorry I am struggling to follow the source code of Sorcery to fix it

satb avatar Sep 26 '12 21:09 satb

it looks fixed on this commit https://github.com/NoamB/sorcery/commit/1b1e7d9f1550fcd91ab8b1d8ff15b5387ab77c53#lib/sorcery/controller.rb

kuboon avatar Nov 06 '12 10:11 kuboon

This is still an issue. reset_session wipes out all sessions, including the _csrf_token

At the moment, my quick fix. I have: old_session = session reset_session # Protect from session fixation attacks form_authenticity_token # Generate the _csrf_token session = old_session

I am also wondering why Sorcery destroys sessions via reset_session, but does not recreate a new token for the _csrf_token? Shouldn't _csrf_token be regenerated on every sign-in?

For example. the login method at https://github.com/NoamB/sorcery/blob/master/lib/sorcery/controller.rb#L31 restores old sessions but does not regenerate a new csrf_token. Shouldn't it have done that?

krzkrzkrz avatar Feb 05 '13 03:02 krzkrzkrz

I agree with @krzkrzkrz, _csrf_token shouldn't be regenerated or should at least have an option to persist it.

BlakeWilliams avatar Mar 13 '13 22:03 BlakeWilliams

Is it really the same session if you had to log in again?

chak avatar Feb 21 '14 02:02 chak

It's been forever since I've used Sorcery in a project, but I hit some issue where it wiping out all parts of the session caused some crazy bugs. It was kind of a pain to figure out and could have been avoided with a flag to allow/disallow it wiping out everything in the session.

BlakeWilliams avatar Feb 21 '14 02:02 BlakeWilliams

Devise currently clears csrf_token on login by default. There's an option to disable it, which is one of possible ways of dealing with this issue. I do it different way in the application I'm working on: I send the new token in response after login/logout action. I've got client web and mobile app. Web app updates meta tag with the new token and web app overrides currently used token and uses the new one with following requests.

I agree we shouldn't clear all the session data on login (I'll work on it soon), but I don't think we should leave the same csrf token by default.

arnvald avatar Jul 08 '14 12:07 arnvald