When dealing with user input, or when deserializing classnamesfrom user input, for example
model = params[:type].camelize.constantize
item = model.find(params[:id])
A user could provide an arbitrary modelname inparams[:type]and thus find an objectin a different model than expected. Now, there might be other code that will fail if the item doesn’t respond to a certain attribute name.But in some cases, Railswill show something that this user isnot allowedto see. If the code continued like this, it could also update the item:
item.update_attribute(:state, params[:state])
What can I do against it?
When dealing with user-provided class names (and constantize), it’s best to use a whitelist of possible inputs rather than trusting the user. I know, your intention wasn’t to trust the user input, but just take out a bit of repetition.Let’s add a whitelist check and we’ve got the Ruby class injection problem covered:
if ['user', 'account'].include?(params[:type])
model = params[:type].camelize.constantize
item = model.find(params[:id])
end