Wednesday, November 6, 2013

Stealing user session with open-redirect bug in Rails

Is open redirect bad for your website?
If we don't take into account "phishing", how can be open redirect dangerous? 
Mind reading http://homakov.blogspot.com/2013/03/redirecturi-is-achilles-heel-of-oauth.html because any redirect to 3rd party website will leak facebook access_tokens of your users. 
So innocent open redirect on logout will simply reveal access_token of current user when we set redirect_uri to Client/logout?to=3rdparty
That's really bad. Users won't be happy to see your client posting spam on behalf of their accounts. 

What about open redirect in Rails?
As I previously mentioned in my blog posts, Rails loves playing with arguments. You can send :back, or "location" or :location => "location" or ->{some proc} or :protocol=>"https", :host=>"google.com" etc. So because of this line
redirect_to params[:to]
attacker has multiple ways to compromise the redirect.

1. params[:to][0] == '/' is not good protection, since //google.com is a legit URL. (By the way if you use regexp avoid $^, luke)
2. XSS by sending ?to[protocol]=javascript:payload()//&to[status]=200
3. Discovered yesterday, we can see plain HTTP headers in response body by sending ?to[status]=1

Live demo on Songkick

Step 1, open with GET or POST params
https://www.songkick.com/session/new?success_url[protocol]=javascript&success_url[host]=%250Alocation=name//&success_url[status]=200

Step 2, user clicks on the XSS link and executes payload from window name

Step 3, payload parses broken HTTP response and leaks httpOnly session cookie
https://www.songkick.com/session/new?success_url[status]=1

Frankly, this bug is really common. I found it in more than 5 popular rails startups though I only started checking.
If you need careful security audit (or brutal pentest) of your app, visit http://www.sakurity.com/

2 comments:

  1. I have also noticed one more peculiar thing in Rails app. The way they implement their session tokens. I have seen 3 cases till now where the session token is a combination of some Base64 encoded string + random number. When you base64 decode the string, you can see the sessionID and the CSRF token. This same CSRF token is then used to prevent CSRF as a header in further requests. I am not sure if implementing or having the CSRF token in the session cookie is a good thing or not.

    ReplyDelete
    Replies
    1. yes that's normal signed cookie and it's secure implementation

      Delete