Reputation: 2911
I have already read some posts, such as Value whitelist using strong parameters in Rails 4, but it's not quite what I need.
I have a controller which takes an ID and loads a model. It also optionally takes a query string param (style
) which can be one of 3 values, small
, medium
or large
. This is passed to a method on the model which uses it to fetch an attached image (using paperclip). I noticed that if I pass an invalid param (eg style=wibble
), then I get a 400 error and a notice that the internal file path doesn't exist. Brakeman also notes this as a security issue...
def show
style = params[:style] || :medium
thing = Model.find(params[:id])
path = "#{Rails.root}/public#{thing.image_url(style)}"
content_type = thing.image.content_type || 'image/png'
send_file path, type: content_type, disposition: 'inline'
end
We use ActionController Parameters elsewhere to great effect; but I cannot see how that could "whitelist" a parameters options? Everywhere I have seen says to use a model validator, but that's assuming I'm submitting a parameter to update a model, which I am not.
I'm aware I could do something like:
return head :not_found unless %w(small medium large).include? style
Is this the best way?
Upvotes: 5
Views: 4441
Reputation: 2575
I wrote a gem that extends ActionController::Parameters
for exactly this purpose: whitelisting parameter values. It's simple and lightweight. You would use it like this:
def model_params
params.require(:model).permit(:style, :other_attribute).allow(style: %w[small medium large])
end
Hope you find it useful
https://github.com/msimonborg/allowable
Upvotes: 5
Reputation: 54882
First, you need to define a Constant white-listing all the valid style
values (I would argue that size_type
is a more explicit name). (Watch out for the Symbol / String comparisons).
Then, you either return a 404 if the params[:style]
is not included in the white-listed values OR you fallback to 'medium'
:
style = Model::AVAILABLE_SIZE_TYPES.include?(params[:style]) ? params[:style] || Model::AVAILABLE_SIZE_TYPES.first
Personally, I don't like fallbacks for user's input. They did something wrong (manipulated the URL, changed a value in a form, etc), they deserve to get an error page.
I implied the constant is defined in the Model, but it should not be there as it is not related to the business logic but related to the display of the Model. If you have a ModelDecorator, define it there.
Upvotes: 4