Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Rails puts csrf token like this

I've never used Rails (that only could answer my question), but I see it puts CSRF tokens in each page with forms.
What I don't understand is why it uses two meta tags for that:

<meta name="csrf-token" content="<%= form_authenticity_token %>" />
<meta name="csrf-param" content="authenticity_token" />

Why not just the csrf-token meta?

<meta name="csrf-token" content="<%= form_authenticity_token %>" />

What's the use of csrf-param?

like image 304
Pherrymason Avatar asked Feb 20 '23 08:02

Pherrymason


2 Answers

Rails allows you to do a lot of configuration under the hood related to the CSRF token. If you like, you can change the name of the param -- but if you do, the jQuery UJS driver needs to know the name of the new parameter (since it's used in Ajax requests). That's why there are two meta params here: the first is the actual authenticity token, obviously, but the second is required by Rails' JavaScript drivers in order to even know the name of the first one. (You can see this in action in the jQuery driver or the Prototype driver.)

You could argue this gets you into some kind of crazy loop -- why can't you rename the csrf-param meta tag with another meta tag? I think this was done to allow Rails to easily adopt existing CSRF solutions without needing a lot of manual overrides. Also it allows your apps to be slightly future-proofed. If the HTML5 standard ever adopts an official tag for CSRF tokens, and Rails opts to change the default CSRF tag in a future version, the JavaScript drivers won't have to change at all.

Ultimately, I think that's closest to the real reason this exists: it's insurance against future changes in the CSRF system, preventing unnecessary and possibly extremely annoying deprecations down the road.

like image 136
Veraticus Avatar answered Feb 25 '23 11:02

Veraticus


csrf-param contains the name of the parameter and csrf-token is the value of the parameter. So, your form would look like this :

<form action="/" method="post">
  <input type="hidden" name="authenticity_token" value="OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWEwYzU1YWQwMTVhM2JmNGYxYjJiMGI4MjkGTfMTVi
  MGYwMGEwOA==">
  …
  </form>
like image 20
ddb Avatar answered Feb 25 '23 11:02

ddb