-
Notifications
You must be signed in to change notification settings - Fork 188
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
Address CVE-2019-16782 #151
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,8 +38,8 @@ def setup_sessid_compatibility! | |
# Reset column info since it may be stale. | ||
reset_column_information | ||
if columns_hash['sessid'] | ||
def self.find_by_session_id(*args) | ||
find_by_sessid(*args) | ||
def self.find_by_session_id(session_id) | ||
find_by_sessid(session_id) | ||
end | ||
|
||
define_method(:session_id) { sessid } | ||
|
@@ -71,6 +71,27 @@ def loaded? | |
@data | ||
end | ||
|
||
# This method was introduced when addressing CVE-2019-16782 | ||
# (see https://github.com/rack/rack/security/advisories/GHSA-hrqr-hxpp-chr3). | ||
# Sessions created on version <= 1.1.3 were guessable via a timing attack. | ||
# To secure sessions created on those old versions, this method can be called | ||
# on all existing sessions in the database. Users will not lose their session | ||
# when this is done. | ||
def secure! | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this method was added? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess this should probably be documented. Normally, sessions are only upgraded to secure sessions, when a user makes a request using the insecure session. This allows existing user sessions to be upgraded to secure sessions while the users are offline. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will allow maintainers to create a migration which basically performs a An remark in the README.md would be great though 💡 |
||
session_id_column = if self.class.columns_hash['sessid'] | ||
:sessid | ||
else | ||
:session_id | ||
end | ||
raw_session_id = read_attribute(session_id_column) | ||
if ActionDispatch::Session::ActiveRecordStore.private_session_id?(raw_session_id) | ||
# is already private, nothing to do | ||
else | ||
session_id_object = Rack::Session::SessionId.new(raw_session_id) | ||
update_column(session_id_column, session_id_object.private_id) | ||
end | ||
end | ||
|
||
private | ||
def serialize_data! | ||
unless loaded? | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this check? How the user will get access to a private id?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't add this protection, the fallback mechanism allows an attacker to guess the private id with a timing attack similar to the original vulnerability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imagine
public_id
just being aprivate_id
in disguise. The attacker would send anpublic_key
which is in fact aprivate_id
! Line 136 will fail becausepublic_id
(aka "evil private_id") will be a double hashedprivate_id
. This will cause line 139 to be executed. Which is basically the same insecure behaviour is as it is right now.This line prevents this. If
public_id
is in fact aprivate_id
it won't get used at all and no lookup will be performed.Instead a new and secure key/session will be generated and used ✅