File tree 3 files changed +36
-1
lines changed
lib/action_dispatch/session
3 files changed +36
-1
lines changed Original file line number Diff line number Diff line change @@ -38,6 +38,12 @@ been updated in the last 30 days. The 30 days cutoff can be changed using the
38
38
Configuration
39
39
--------------
40
40
41
+ Disable fallback to use insecure session by providing the option ` secure_session_only `
42
+ when setting up the session store.
43
+ ``` ruby
44
+ Rails .application.config.session_store :active_record_store , :key => ' _my_app_session' , :secure_session_only => true
45
+ ```
46
+
41
47
The default assumes a ` sessions ` table with columns:
42
48
43
49
* ` id ` (numeric primary key),
Original file line number Diff line number Diff line change @@ -60,6 +60,12 @@ class ActiveRecordStore < ActionDispatch::Session::AbstractSecureStore
60
60
SESSION_RECORD_KEY = 'rack.session.record'
61
61
ENV_SESSION_OPTIONS_KEY = Rack ::RACK_SESSION_OPTIONS
62
62
63
+ def initialize ( app , options = { } )
64
+ @secure_session_only = options . delete ( :secure_session_only ) { false }
65
+ super ( app , options )
66
+ end
67
+
68
+
63
69
private
64
70
def get_session ( request , sid )
65
71
logger . silence do
@@ -136,7 +142,7 @@ def get_session_with_fallback(sid)
136
142
if sid && !self . class . private_session_id? ( sid . public_id )
137
143
if ( secure_session = session_class . find_by_session_id ( sid . private_id ) )
138
144
secure_session
139
- elsif ( insecure_session = session_class . find_by_session_id ( sid . public_id ) )
145
+ elsif ! @secure_session_only && ( insecure_session = session_class . find_by_session_id ( sid . public_id ) )
140
146
insecure_session . session_id = sid . private_id # this causes the session to be secured
141
147
insecure_session
142
148
end
Original file line number Diff line number Diff line change @@ -299,6 +299,29 @@ def test_session_store_with_all_domains
299
299
end
300
300
end
301
301
302
+ define_method :"test_unsecured_sessions_are_ignored_when_insecure_fallback_is_disabled_#{ class_name } " do
303
+ with_store ( class_name ) do
304
+ with_test_route_set ( secure_session_only : true ) do
305
+ get '/set_session_value' , params : { foo : 'baz' }
306
+ assert_response :success
307
+ public_session_id = cookies [ '_session_id' ]
308
+
309
+ session = ActiveRecord ::SessionStore ::Session . last
310
+ session . data # otherwise we cannot save
311
+ session . session_id = public_session_id
312
+ session . save!
313
+
314
+ get '/get_session_value'
315
+ assert_response :success
316
+
317
+ session . reload
318
+ new_session = ActiveRecord ::SessionStore ::Session . last
319
+ assert_not_equal public_session_id , new_session . session_id
320
+ assert_not_equal session . session_id , new_session . session_id
321
+ end
322
+ end
323
+ end
324
+
302
325
# to avoid a different kind of timing attack
303
326
define_method :"test_sessions_cannot_be_retrieved_by_their_private_session_id_for_#{ class_name } " do
304
327
with_store ( class_name ) do
You can’t perform that action at this time.
0 commit comments