Logout is broken by default in Ruby on Rails Web applications

UPDATE: This issue has received press coverage and made it into the Open Sourced Vulnerability Database (OSVDB) available at http://osvdb.org/show/osvdb/97726. I will follow up on this post with more technical details as well as my research results from studying this issue in the wild.

 

Ruby on Rails Web applications versions 2.0 through 4.0 are by default vulnerable to an oft-overlooked Web application security issue: Session cookies are valid for life.* The fix is to configure your Rails app to store most session information on the server side in the database.

Background

The default Rails session storage mechanism is the CookieStore, which holds the entire user session hash on the client side in the Web browser as a cookie. In this configuration there is no entry in a “sessions” database table for your Rails app to delete upon logout.

My concern is more than just current session hijacking via Firesheep or similar; a malicious user could use the stolen cookie from any authenticated request by the user to log in as them at any point in the future.

When a user logs out what happens is not what you would expect. Again, no entry in a “sessions” table exists to delete. Instead, Rails will issue a new, empty-ish cookie to the user’s browser in order to overwrite the one granted when the user originally authenticated, and instruct the Web browser to use this newest one from this point forth. This relies on good browser behavior. But remember, the previous cookie is still valid. There is no way to invalidate these old cookies upon sign out with the default Rails configuration. In addition to network snooping (session sidejacking) and XSS, this presents a problem for users accessing your site via a shared or public computer, or perhaps over a faulty network connection that might drop the very last HTTP response requesting that the user’s browser overwrite the stored authenticated cookie. Also, when your users forget to logout, they will not be able to log themselves out of that living session from a different computer, and anyone who discovers the stored cookie can use it indefinitely.

The default cookie name is:

“your_app_session”

And before Base64 encoding and URL encoding, the cookie value may look something like this with actual values for “[String]”:

{ I"session_id:EF"%[String]I"_csrf_token;FI"1[String]=;FI"user_credentials;FI"[String];TI"user_credentials_id;Fi

While Rails 4 switched to encrypting the value of the cookie, doing so does not eliminate this issue.

Separately, it is a good design for your Web app to require that the user supply their current password before changing sensitive fields such as password or email address. If the CookieStore-stored session were to be hijacked, the malicious user could change the user’s password: 1) immediately invalidating the legitimate user’s cookie and thus slamming your app’s doors in their face and 2) disallowing the legitimate user the ability to log back into their account.

A note about a red herring: if you use the Authlogic gem you may notice a field called “persistence_token” in your users table and believe that you are already using server-side storage for most of your session data. In my testing of the default CookieStore configuration, the field did not appear to serve a purpose.

Remediation

Switch to ActiveRecordStore or something else from this list. Switching away from CookieStore is said to be slower. After switching, the cookie will contain a value for “session_id” which corresponds to an entry in your database’s sessions table. You will need to keep in mind replicating session data across multiple databases if you have more than one active behind a load balancer.

Happy hacking! Email me with questions: Main@GSMcNamara.com

*In my testing, the only methods to invalidate these cookies are for the user to change their password or for systems administrators to change the application secret. Both are infrequent occurrences.


Share

21 thoughts on “Logout is broken by default in Ruby on Rails Web applications

    • Thanks for posting this technical article! It was a joy to read.

      It should be noted that after hijacking a session or resuming a one thought to be dead by the real user, a change by the malicious user of any of those session variables would immediately invalidate the stored cookie on the real user’s machine, and then they would be locked out of the app. They might also then not be able to re-authenticate, if the hijacker were able to set fields used to authenticate, such as username, password, or email address.

  1. Pingback: Some Versions of Ruby on Rails Could Expose Cookies | Threatpost

  2. Pingback: Security Issue in Ruby on Rails Could Expose Cookies « Cyber Security Aid

  3. Pingback: Vulnerability in Ruby on Rails 2.0 – 4.0 Allows Hackers to Hijack Accounts | Cyber Security Infotech(P) Ltd

  4. Pingback: Security News #0×54 | CyberOperations

  5. Pingback: Security Vulnerability with Django Cookie-Based Sessions | MaverickBlogging

  6. Pingback: Logout is broken by default in Rails | Boardmad

  7. Pingback: CookieStore vulnerability in Rails 2.x, 3.x, 4.x. | Rocketboom

  8. Pingback: CookieStore vulnerability in Rails 2.x, 3.x, 4.x. | Enjoying The Moment

  9. Pingback: How bad is rails’ cookie system? |

  10. Pingback: Episode 112 – Facebook CSRF, KnockoutJS 3 | WebDevRadio

  11. Pingback: Episode 112 – Facebook CSRF, KnockoutJS 3 | PHP Podcasts

  12. Pingback: Ruby on Rails ใช้ CookieStore เป็นมาตรฐาน หลายบริการสามารถใช้ cookie เดิมล็อกอินซ้ำได้ | PantipGuide.com

  13. Pingback: Ruby on Rails ใช้ CookieStore เป็นมาตรฐาน หลายบริการสามารถใช้ cookie เดิมล็อกอินซ้ำได้ | Webtheboy.com เว็บไซต์วาไรตี้

  14. Pingback: Ruby on Rails ใช้ CookieStore เป็นมาตรฐาน หลายบริการสามารถใช้ cookie เดิมล็อกอินซ้ำได้ | ละครย้อนหลัง,ข่าว,คลิปว

  15. Pingback: Ruby on Rails ใช้ CookieStore เป็นมาตรฐาน หลายบริการสามารถใช้ cookie เดิมล็อกอินซ้ำได้ | ข่าวไอที

  16. Pingback: Improving Rails Security with CacheStore | Second Forge

  17. Pingback: Top 10 Web Hacking Techniques 2013 | My reading

  18. Pingback: Top 10 Web Hacking Techniques 2013 | WhiteHat Security Blog

  19. Pingback: Logging Out of a Rails App That Uses session_store = :cookie_store | Alaina Hardie

Leave a Reply