Cookie, Session & Rails CSRF Protection
What
Cookies
A cookie is a small piece of data a server sends to a user’s web browser. The browser stores cookies and send them back to the sever in later requests. It’s the only way to store limited amounts of data, remembering state information. Since by default HTTP protocol is stateless
.
The server is able to set cookies using Set-Cookie
header and read cookies using Cookie
header, in response and request respectively.
This article explains details.
Session
A session can refer to one of two things:
- A place to store data during one request that can be used in later requests.
- A time period during which the user is logged in to your application.
Generally, once a user logs in, the application stores his information in the session (the place). And use that information in subsequent request to make sure the user is valid and logged-in (the period).
For rails, several store mechanisms are provided, you can store session data in any of them via a unified
API. Notice, all of below options have the prerequisite of Cookies
enabled on the browser, which stores session_id
.
CookieStore
: Store all data inside a cookie, in addition to the session IDCacheStore
: Store data inside the Rails cacheActiveRecordStore
: Store the data in the databaseMemCacheStore
: Use a Memcached cluster of servers
A session id is generated when the session data is stored. It’ set in the cookie
, no matter whichever store you use.
This article has great explanation.
Why
The key difference between sessions and cookies is that sessions are saved on the server side while cookies are saved on the client side.
How
CSRF & CSRF Protection
Cross-site request forgery is a malicious exploit of a website that unauthorized commands are transmitted from a user the website trusts. The attacker usually induces users to performa actions they do not intend to by a fake form
, which triggers state change request, e.g, transfer money from users’ account to the attacker’s.
Where
Rails insert CSRF-token
into both form
and meta
tag.
The former one will be sent along in the payload when form is submitted.
The latter one is to give javascript requests that are not tied to a form an easy way of getting the token. If you use the jquery-ujs library the content of that meta tag is automatically added (as a request header) to any ajax requests made (in the X-Csrf-Token
request header?).
Token is generated on the fly for each request. During generation, it’s inserted into session, making sure the one embedded in html alway matches the one in the session.
When
Since a request can pass in the CSRF-token
through form params or X-Csrf-Token
header, Rails requires at least one of those tokens match the one in the session.
# Possible authenticity tokens sent in the request.
def request_authenticity_tokens
[form_authenticity_param, request.x_csrf_token]
end
Check this article for detailed explanation.
Who
References
-
[A Deep Dive into CSRF Protection in Rails by Alex Taylor Ruby Inside Medium](https://medium.com/rubyinside/a-deep-dive-into-csrf-protection-in-rails-19fa0a42c0ef) -
[Using HTTP cookies - HTTP MDN (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) - https://stackoverflow.com/a/359482/10616866
-
[What Are Sessions? How Do They Work? Baeldung on Computer Science](https://www.baeldung.com/cs/web-sessions) - Sessions in Rails: Everything You Need to Know (writesoftwarewell.com)