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_encoding
doesn’t work on an API controller.@rahul342 You could try including
ActionController::ParameterEncoding
in your controller.@rafaelfranca and I had a chat about this and we’ve decided to move the encoding into the controller, with
AD::Request
using 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::Request
is 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#serve
since 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 ?