-
Notifications
You must be signed in to change notification settings - Fork 164
Stringify all params values #82
Description
Rails Params Parsing is magic. You never know what it can lead to. Nested hash in params[:id], Array full of nils etc.
- Array stuffed with nils.
User.find_by_token(params[:token])
can find a user with empty token if we provide params[:token]=[nil] or [1,nil]. It was possible half a year ago, and then 'reinvented' with JSON/XML params parsers. - Nested hashes - same problem would happen if we could get symbols in keys in {"select"=>"code"}.
- Did you know the trick with bruteforcing?: instead of passing ?token=abc you can pass ?token[]=abc2&token[]=abc2... Or for example username[]=testingfirst&username[]=testingsecond.. in
find_by_username_and_password(params[:username], sha(params[:password))
Thus we need a reliable tool to get exact structure of params we asked for. Some people suggest to stringify it in ActiveRecord and find_by_ should accept only strings - i think it's just killing useful tool for no reason.
Maybe strong_params should control all incoming params(before_filter), not only for mass assignment purposes? e.g.
class PeopleController < ActionController::Base
params.require(:person).permit(:name, :age)
def search
Person.find_by_age(params[:person][:age]) #if we pass ?person[age][]=1&person[age][]=2&person[age][]=3 it will be casted to "[1,2,3]"
If developer needs nested structures he will specify it explicitly in controller. Not so agile, but user input is the last thing that should be agile. will fix rails/rails#8831 and possible future vulnerabilities in params, once and for all.
P.S I might be wrong thinking developer expects static structure - please point out if there are use cases with agile and random structure