POSTing raw JSON data with Rails 3.2.11 and RSpec

Daniel Vandersluis picture Daniel Vandersluis · Feb 8, 2013 · Viewed 35.2k times · Source

In order to ensure that my application is not vulnerable to this exploit, I am trying to create a controller test in RSpec to cover it. In order to do so, I need to be able to post raw JSON, but I haven't seemed to find a way to do that. In doing some research, I've determined that there at least used to be a way to do so using the RAW_POST_DATA header, but this doesn't seem to work anymore:

it "should not be exploitable by using an integer token value" do
  request.env["CONTENT_TYPE"] = "application/json"
  request.env["RAW_POST_DATA"]  = { token: 0 }.to_json
  post :reset_password
end

When I look at the params hash, token is not set at all, and it just contains { "controller" => "user", "action" => "reset_password" }. I get the same results when trying to use XML, or even when trying to just use regular post data, in all cases, it seems to not set it period.

I know that with the recent Rails vulnerabilities, the way parameters are hashed was changed, but is there still a way to post raw data through RSpec? Can I somehow directly use Rack::Test::Methods?

Answer

Daniel Vandersluis picture Daniel Vandersluis · Feb 8, 2013

As far as I have been able to tell, sending raw POST data is no longer possible within a controller spec. However, it can be done pretty easily in a request spec:

describe "Example", :type => :request do
  params = { token: 0 }
  post "/user/reset_password", params.to_json, { 'CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json' }
  #=> params contains { "controller" => "user", "action" => "reset_password", "token" => 0 }
end