rails: Accessing request.params breaks parameter encoding validation
Given a controller:
class FooController < ApplicationController
skip_parameter_encoding :index
skip_before_action :verify_authenticity_token
def index
head :ok
end
end
parameters in the index action should be able to carry any payload. For example, this should work
require "net/http"
uri = URI("http://localhost:3000")
Net::HTTP.post_form(uri, "foo" => "\xe1") # Invalid UTF-8.
and it does.
However, a middleware as innocent as
class FooMiddleware
def initialize(app)
@app = app
end
def call(env)
request = ActionDispatch::Request.new(env)
request.params
@app.call(request.env)
end
end
interferes somehow with parameter encoding validation, and the request now raises
ActionController::BadRequest (Invalid request parameters: Invalid encoding for parameter: �)
About this issue
- Original URL
- State: open
- Created 3 years ago
- Comments: 27 (15 by maintainers)
So, what is the fix for this issue in August 2022?
skip_parameter_encodingdoesn’t work on an API controller.@rahul342 You could try including
ActionController::ParameterEncodingin your controller.@rafaelfranca and I had a chat about this and we’ve decided to move the encoding into the controller, with
AD::Requestusing binary encoding. I’ll update the PR I opened to move the encoding from the router into the controller and ensure we’ve documented the fact that encoding withAD::Requestis binary since the controller context might not be available yet.Perfect @adrianna-chang-shopify!
Another option could be somewhere near
ActionDispatch::Routing::RouteSet#call, orActionDispatch::Routing::RouteSet::Dispatcher#servesince that seems to be the lowest boundary before passing the request to the controller (if my limited understanding of this part of the framework is right). Though the dispatcher should probably stay at dispatching only.Let’s see what @rafaelfranca says!
Possibly this changed in https://github.com/rails/rails/pull/40124 ?