Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing #13

Open
chriso0710 opened this issue May 18, 2017 · 4 comments
Open

Testing #13

chriso0710 opened this issue May 18, 2017 · 4 comments

Comments

@chriso0710
Copy link

Hi all,

I am trying to test a Sinatra app which has rack_csrf enabled for forms and most routes.
Some routes do not have csrf enabled, as they belong to the apps API.

Does it make any sense to test csrf protection (with minitest and rack-test) for all routes, to check that forms are correctly csrf-protected and API routes are not? What would be the best practice for this? Or would it be best to just ignore this and disable/skip rack_csrf completely in test mode?

Thanks and best regards
Christian

@baldowl
Copy link
Owner

baldowl commented May 19, 2017

YMMV, but yes, I would test at least the routes which are supposed to be protected with rack-test, just to avoid "surprises" down the road.

@IanBurry
Copy link

IanBurry commented Aug 2, 2017

Ok, rack_csrf is breaking my rspec tests, so I'm going to go ahead and be that 'noob'

How do you configure it to work in a test environment? It's there. It's throwing Rack::Csrf::InvalidCsrfToken, but I can't seem to change its behavior either in spec_helper or within tests

@chriso0710
Copy link
Author

ATM I am disabling CSRF in testing like that in a sinatra configure block:

use Rack::Csrf, { :raise => false, :skip => ['POST:.*', 'PUT:.*', 'DELETE:.*', 'PATCH:.*'] }

Did not have the time to make it work in testing. But my ultimate goal sometime in the future would be to enable it again for rack-test like @baldowl suggested...

@baldowl
Copy link
Owner

baldowl commented Aug 3, 2017

@IanBurry: if everything is behind Rack::Csrf, skipping it in test environment is a no brainer. However, if you wan to test it, you can follow a couple of different routes.

Rack::Test provides an env method which can be used to insert whatever you want in the fake env used by post & co.; however, that env method does not expose the object and thus you cannot use the fake env with Rack::Csrf.token and the only solution I can think of is using a static, fake, token, like this:

it 'responds correctly' do
  env 'rack.session', Rack::Csrf.key => 'super-fake-token'
  post '/protected_form', :a_field => 'a value', Rack::Csrf.field => 'super-fake-token'
  expect(last_response).to be_ok
end

Alternatively (and don't tell anyone I told you to do it 😜) you can mess with Rack::Test's internals:

it 'responds correctly' do
  env_object = current_session.instance_variable_get :@env
  env_object['rack.session'] = {}
  token = Rack::Csrf.token env_object
  post '/protected_form', :a_field => 'a value', Rack::Csrf.field => token
  expect(last_response).to be_ok
end

Whatever you choose, of course you can/should extract and polish the code which injects the token (the fake, static, one or the real token) or your specs will smell bad pretty soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants