OptinParsing
Automatic parsing of json and xml request bodies requires care. Beyond vulnerabilities in the parameter parsing code itself the ability for a requester to be able to control the type of parameters combines badly with some of mysql's typecasting logic, for example
User.find_by_secret_token(0)
returns a user with a secret token that does not look to mysql like a valid integer instead of returning nil. Rails 3.2.12 contains some mitigations for this (the above example does not work on rails 3.2.12 and above) but can't catch all cases. You can avoid this by calling to_s
on parameters that should be strings. For more details see the security advisory. It is easy to forget to do this and it goes against the philosophy of "secure by default".
An easy mitigation is to simply disable this parsing by removing mime types from ActionDispatch::ParamsParser::DEFAULT_PARSERS
this is a change that affects all controllers.
This gem allows the automatic parameter parsing to be turned on per controller and per action, so that (for example) api endpoints that need to accept json and/or xml can continue to work (and be audited for their parameter usage) but reducing the surface of attack by not allowing json bodies for all those requests that do not need it.
The default is for such parsing to be disabled for all controllers.
Installation
Add this line to your application's Gemfile:
gem 'optin_parsing'
And then execute:
$ bundle
Or install it yourself as:
$ gem install optin_parsing
Usage
Allow a controller to parse xml bodies automatically
class MyController < ApplicationController
parses :xml
end
Allow a controller to parse json bodies automatically, only for a certain action
class MyController < ApplicationController
parses :json, :only => :some_action
end
Allow a controller to parse json bodies automatically, except for certain actions
class MyController < ApplicationController
parses :json, :except => [:some_exempt_action, :another_exempt_action]
end
Allow a controller to parse a specific mime type, with a custom strategy
class MyController < ApplicationController
parses Mime::YAML do |raw_post|
#parse raw_post and return a hash of data
end
end
Subclasses inherit their parent classes' settings
Caveats
Ordinarily parameters are parsed by a Rack middleware. This gem defers parsing until the request is processed by the controller: the parsed parameters will not be available to middleware code that runs before this.
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request