Quantcast
Channel: coderrr » security
Viewing all articles
Browse latest Browse all 10

Rails CSRF vulnerability explanation

$
0
0

I know this is old and I also usually don’t like posting duplicate info that’s already easily findable elsewhere, but since I discovered this I figured I would blog about it.

Since I find security issues interesting I was reading through a Rails lighthouse ticket dealing with authenticity tokens on AJAX requests. I’ll leave out most of the details of the issue they were discussing but it came down to them deciding to rely on trusting the browser sending only multipart/form-data or application/x-www-form-urlencoded encoding types (enctype) when submitting forms.

We can use the Content-Type of the request because browsers can’t change it. They will only ever send html, url encoded or multipart.

I was in the mood to find a hole so I immediately thought about trying to submit with a different enctype. I tried a few random ones but the browser would always default back to form-urlencoded. So I decided to open up the source for Firefox. After a bit of digging I found this:

} else if (method == NS_FORM_METHOD_POST &&
              enctype == NS_FORM_ENCTYPE_TEXTPLAIN) {
     *aFormSubmission = new nsFSTextPlain(charset, encoder,
                                          formProcessor, bidiOptions);

So immediately I tried <form method="post" enctype="text/plain" ... and voila I could submit without an auth token. So then I thought well maybe Firefox is just crazy so I dug into the Webkit source and found similar code:

} else if (type.contains("text", false) || type.contains("plain", false)) {
    m_enctype = "text/plain";
    m_multipart = false;

In retrospect it would have been a lot quicker if I had found this webpage which lists exactly how each browser deals with enctype. But never trust a website… only trust source code :P Also digging through code is a lot more fun.

There was one more step to make the CSRF scenario complete. Even though I could submit the form without having Rails raise a security exception, it wouldn’t use any of the input values from the form. But I quickly found that any parameters passed in the query string would still be parsed and available. So something like

<form method="post" enctype="text/plain" action="/update_email?email=atta@cker.com&email_confirmation=atta@cker.com">

would do the trick.

So anyway to briefly overview what the vulnerability means: If you are using an affected Rails version (2.1.0-2.1.2 and 2.2.0-2.2.1) anyone can perform CSRF attacks on your application. Meaning if you have a form on your site which updates a user’s email address and a user of your site (who is logged in) visits a malicious page, the attacker can change that user’s email address (after which they can probably reset their password and gain full access to the account).



Viewing all articles
Browse latest Browse all 10

Trending Articles