As suggested in #16299([1]), this method should be a new public API for
retrieving unfiltered parameters from `ActionController::Parameters`
object, given that `Parameters#to_hash` will no longer work in Rails
5.0+ as we stop inheriting `Parameters` from `Hash`.
[1]: https://github.com/rails/rails/pull/16299#issuecomment-50220919
This is to make sure that `permitted` status is maintained on the
resulting object.
I found these methods that needs to be redefined by looking for
`self.class.new` in the code.
* extract!
* transform_keys
* transform_values
`ActionController::Parameters#to_h` now returns a `Hash` with
unpermitted keys removed. This change is to reflect on a security
concern where some method performed on an `ActionController::Parameters`
may yield a `Hash` object which does not maintain `permitted?` status.
If you would like to get a `Hash` with all the keys intact, duplicate
and mark it as permitted before calling `#to_h`.
params = ActionController::Parameters.new(name: 'Senjougahara Hitagi')
params.to_h # => {}
unsafe_params = params.dup.permit!
unsafe_params.to_h # => {"name"=>"Senjougahara Hitagi"}
safe_params = params.permit(:name)
safe_params.to_h # => {"name"=>"Senjougahara Hitagi"}
This change is consider a stopgap as we cannot chage the code to stop
`ActionController::Parameters` to inherit from
`HashWithIndifferentAccess` in the next minor release.
Also, adding a CHANGELOG entry to mention that
`ActionController::Parameters` will not inheriting from
`HashWithIndifferentAccess` in the next major version.
We cannot cache keys because arrays are mutable. We rather want to cache
the arrays. This behaviour is tailor-made for the usage pattern strongs
params is designed for.
In a forthcoming commit I am going to add a test that covers why we need
to cache by value.
Every strong params instance has a live span of a request, the cache goes
away with the object. Since strong params have such a concrete intention,
it would be interesting to see if there are actually any real-world use
cases that are an actual leak, one that practically may matter.
I am not convinced that the theoretical leak has any practical consequences,
but if it can be shown there are, then I believe we should either get rid of
the cache (which is an optimization), or else wipe it in the mutating API.
This reverts commit e63be2769c.