cURLing with Rails' Authenticity Token
Our event, Developers Developers Developers Developers, is this weekend.
When the amount of registrations reached the capacity of the venue, we removed the registration form from the website.
However, we left the Rails route and controller around and encouraged students to register by reading the source code of the application and coding their way in. We pointed them to the staging app so they could practice before registering via the production app.
So we just need to POST to
/registrations with the right params,
right? Right. However, "the right params" needs to include Rails'
which the framework uses to combat
payload also needs to include a cookie because the
So here's the cURL solution.
curl http://dddd-staging.heroku.com --cookie-jar cookie | grep csrf
That will store the cookies in a file named "cookie" and print out the
authenticity_token you need (it's the value of the content attribute on the
csrf-token meta tag):
<meta name="csrf-param" content="authenticity_token"/> <meta name="csrf-token" content="sNMk592JV2wwHn6DPJ8C5oy/hHDnjIlZBOHyngtTbpQ="/>
Meanwhile, the contents of the cookies file looks like this:
# Netscape HTTP Cookie File # http://curl.haxx.se/rfc/cookie_spec.html # This file was generated by libcurl! Edit at your own risk. #HttpOnly_dddd-staging.heroku.com FALSE / FALSE 0 _dddd_session BAh7...
curl http://dddd-staging.heroku.com/registrations --data "registration[name]=Dan Croak®istration[twitter]=croaky®istration[school_name]=Holy Cross®istration[role]=Developer&authenticity_token=sNMk592JV2wwHn6DPJ8C5oy/hHDnjIlZBOHyngtTbpQ=" --cookie cookie
This adds the
authenticity_token and also includes the cookie from the first
The output will be the original HTML that we fetched and replaced on the page via Ajax when registration was still open:
<div class="student"> <div class="avatar"> <img src="http://avatar.statusok.com/croaky?size=73" /> </div> <div class="student-details"> <div class="name">Dan Croak</div> <div class="twitter">@croaky</div> <div class="role-and-school"> Developer, Holy Cross </div> </div> <h2>Thanks for registering! We can't wait to see you!</> <h3>Follow @<a href="http://twitter.com/thoughtbot">thoughtbot</a> and @<a href="http://twitter.com/greenhornboston">greenhornboston</a> for updates.</h3> <h3>We also invite you to join our private <a href="http://groups.google.com/group/developers-developers-developers-developers">mailing list</a> for speakers and attending students.</h3> </div>
Another Approach: Using Web Inspector
However, we're living in the future here, folks. It's 2011, and we've got a GUI for everything - no need to get Terminal all over your hands.
So let's load the site normally in a web browser, view the HTML source to grab that authenticity token, insert a form into the DOM, then submit it.
I'll be using Chrome and the WebKit Inspector here, but you could also use Firefox and the excellent Firebug plugin.
Step 1: Find the authenticity token
Here I view the HTML source and look for the authenticity token in the
Step 2: Insert a form into the HTML
Here's the registration form that we'll add back into the page. I made sure to insert the right authenticity token:
<form action="/registrations" method="POST"> <input type="text" name="registration[name]" value="Jason Morrison" /> <input type="text" name="registration[twitter]" value="jayunit" /> <input type="text" name="registration[school_name]" value="RIT" /> <input type="text" name="registration[role]" value="Developer" /> <input type="text" name="authenticity_token" value="iKSXdP4+Ir80ABwsmwvX5LjUKdto3n6p99E/+pgmegI=" /> <input type="submit" /> </form>
You can insert the form anywhere. Let's overwrite this paragraph:
Paste in the HTML:
Step 3: Submit the form
Click submit, and you're off to the races.
See you at the event!