RESTful Rails and Mobile Devices
My partner, Karen, has done a remarkable job at creating the web application for our first property. Sadly, I’m responsible for implementing an Android application which invokes it’s powerful magic. Life is good when one stays within the Rails web application, but RESTful interfaces are meant to make exchange of data from machine to machine easy and well defined. If only life were so simple…
Rails implements protection against Cross-Site Request Forgery (CSRF) protection. If you have a look at a form created with Rails, you’ll notice a hidden field for an authenticity_token. This is a hidden field with a randomly generated token to ensure that inauthentic clients can’t muck with your data.
In our application, the login form has the following hidden field lurking:
<input name="authenticity_token" type="hidden" value="XRGy4w54tVmDtzwkLK/DfDIfWcIHf9h8nnwcefpBCeE=" />
This lovely thing is an important mechanism to protect the site from CSRF exploits. If a client does not have the appropriate authentication key, any attempt to POST, DELETE, or PUT will be rejected. This feature can be easily disabled by simply going to the application directory’s config/environment/ directory and adding the following for test, development or production as necessary:
# Disable request forgery protection in test environment config.action_controller.allow_forgery_protection = false
As a default, this is only a default for “test.rb” and none of the others, however while tinkering around with an application on your PC you are most likely invoking the development.rb options. With this option disabled, one can simply us an HTTP post to the URL corresponding to the resource in question as follows. For example, a user model with a login, email and password can be created as follows using cURL:
curl -d "user[login]=Kiwi" -d "user[email]=email@example.com] -d user[password]=wishicouldfly" http://localhost:3000/users
With CSRF protection disabled, this will work fine. Unfortunately the site will have a vulnerability. With it enabled, Rails will cheerfully tell you to pound sand.
Obviously the CSRF implementation is a valuable tool, but one that forces us to think a bit more about the proper mechanism for non-browser clients to access the resources on the site. Sorry to say I haven’t quite figured this one out to my satisfaction, but when I do so I’ll certainly share.
I have a few ideas, so stay tuned…