I just completed the login sections of the Rails Tutorial, so here are my notes.
Session Hijacking
An attack where someone steals a remember token to impersonate a specific user and log in as them.
Four Common Methods to Steal Cookies
- Directly extracting cookies from network packets using specialized software called packet sniffers, targeting packets traveling through poorly secured networks
- Extracting remember tokens from the database
- Cross-site scripting (XSS)
- Directly accessing a user’s computer or smartphone while they’re logged in to take over their session
Countermeasures
- Apply Secure Sockets Layer (SSL) across the entire site to protect network data with encryption, preventing it from being read by packet sniffers
- Instead of storing remember tokens directly in the database, store hashed values of the tokens
- Rails automatically implements countermeasures. Specifically, it automatically escapes all content entered in view templates
- For attacks involving physical access to a logged-in computer, while it’s impossible to provide fundamental defensive measures on the system side, we can minimize secondary damage. Specifically, we always change tokens when a user logs out (from another device, etc.) and use digital signatures when displaying information that may be important for security
Creating Persistent Sessions
- Use a randomly generated string for the remember token
- Set an expiration date when storing tokens in browser cookies
- Convert tokens to hash values before storing them in the database
- Encrypt user IDs stored in browser cookies
- When receiving cookies containing a persistent user ID, search the database using that ID and verify that the cookies’ remember token matches the hash value in the database
To remember users, create a remember token and store a converted digest of that token in the database
| User model | Description
|:-----:|:-----:|
| remember_digest | Memory digest corresponding to the token |
↑
Use the user.remember_token method to access the token (need to implement without storing the token in the database)
While the password attribute is automatically created by the has_secure_password method, remember_token needs to be implemented manually. To implement this, create a “virtual” attribute using attr_accessor.
attr_accessor is virtually equivalent to defining attributes of an object through migration, allowing both writing and reading. While types defined in migrations are static, types for attr_accessor are determined dynamically.
Verifying Encrypted User IDs
- Decrypt the user ID cookie with cookies.signed[:user_id]
- Use bcrypt to verify that cookies[:remember_token] matches remember_digest
- Verify that the provided token matches the user’s remember digest. The code is as follows:
BCrypt::Password.new(remember_digest).is_password?(remember_token)
Rails Methods
has_secure_password
- Enables securely hashed passwords to be stored in the password_digest attribute in the database
- Makes two pairs of virtual attributes available (password and password_confirmation). Also adds validations for existence and matching values
- Makes the authenticate method available (a method that returns the User object if the string argument matches the password, or false if incorrect)
authenticate
A method provided by has_secure_password. Returns the User object if the string argument matches the password, or false if incorrect
See Also