This project is archived and is in readonly mode.

#2845 ✓hold
Piotr Sarnacki

JSON hijacking - some way to protect JSON

Reported by Piotr Sarnacki | June 27th, 2009 @ 10:26 AM | in 3.0.2

As article on haacked says http://haacked.com/archive/2009/06/25/json-hijacking.aspx providing JSON files with Arrays accessed by GET requests can be hijacked when logged user enters bad guy's prepared page. There are 2 workarounds:
* change every GET to POST for json requests * do not provide array and send something like {items: []}

First solution is not good for rails because of REST.

Second solution is fairly easy to implement but not with render:

render :json => @items
# rendering as an array

It would be nice to provide some easy way to return JSON array as JSON object instead of array.

Comments and changes to this ticket

  • thedarkone

    thedarkone June 27th, 2009 @ 11:30 AM

    It's even worse with RJS templates responding to a GET action. You don't even need to tamper with the Array prototype, just get ready to intercept calls to $ and $$ js functions. Maybe a response from an RJS should look like {JavaScript: "$(..)"}?

  • Piotr Sarnacki

    Piotr Sarnacki June 27th, 2009 @ 09:42 PM

    thedarkone:
    Yes, you're right, but with javascript it's obvious that you can execute with this way. JSON is supposed to be not executable.

    Javascript hijacking is another issue and as you suggested it would be good to wrap javascript and eval it on client side.

  • Yehuda Katz (wycats)

    Yehuda Katz (wycats) July 2nd, 2009 @ 01:21 AM

    • Milestone cleared.
    • State changed from “new” to “verified”
    • Assigned user set to “Yehuda Katz (wycats)”

    The right solution to this problem is to return the following:

    while(true) {}
    {json: "here"}
    

    This requires the cooperation of clients, however, and it means that arbitrary web service clients would have to know about and enlist in the fix. Bumping to 3.0 for further analysis.

  • Yehuda Katz (wycats)

    Yehuda Katz (wycats) July 2nd, 2009 @ 07:41 PM

    • State changed from “verified” to “open”
  • Yehuda Katz (wycats)

    Yehuda Katz (wycats) February 24th, 2010 @ 06:58 AM

    • State changed from “open” to “hold”

    A proper solution would be for a plugin to provide a Renderer like :secure_json (so render :secure_json => ...). If we get cooperation with client-side libraries (like jQuery and Prototype), we could perhaps bring it into core eventually. Also keep in mind that this problem can only occur with guessable URLs, so providing secret JSON only at unguessable URLs would be another way to protect against this problem.

  • Jeremy Kemper

    Jeremy Kemper October 15th, 2010 @ 11:01 PM

    • Milestone set to 3.0.2
    • Importance changed from “” to “”

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages