I've just thought of the following situation: When updating a database
entry ruby calls x/update/7 where 7 is the database id. Now if someone
was to copy a form locally and change the form action to 8 (lets assume
they don't have rights to number 8), then would the update work?
Presumably we could add an action to check the user does in fact own the
id number they are trying to update.
However what if that number was 9 and they also owned 9, then they'd
update their own entry (ok serves them right for messing with the system
I guess).
Does rails have some clever way of checking this or do I need to it
manually?
Cheers,
George
--
Posted via http://www.ruby-forum.com/.
All user input needs to be considered malicious until you evaluate
otherwise. The use of params[:id] as in your example is a prime example
of this problem - you are responsible for either (1) verifying that the
user owns the ID when the update is called, or (2) prevent the problem
altoghether by using something other than a URL-based ID to identify
the record (such as by using a session variable rather than the ID
parameter to "remember" the id of the record that is to be updated).
There is no built-in magic in rails to manage this problem for you.....
As you said, if they change the form and run it for an id that they also
own, then shame on them and they deserve what they get. However, as a
good system developer you should probably guard against that.
One way would be to generate something like an MD5 hash value to store
on the table at the time the value is created, and include that as a
hidden field in the form that does the update. Generate the hash from
datetime value + some arbitrary passphrase. Your controller checks the
hash value submitted from teh form against the MD5 hash in the table
before making updates. Since the MD5 hash value is something that could
not be guessed easily, or at all, it will be impossible for the user to
submit an update to :id => 9, for instance, unless they specifically go
through your system and the form they submit has the appropriate MD5
hash.
c.
You describe the convention, but none of that is what "rails does",
since it's up to the programmer to do anything beyond the basic CRUD.
To keep security, can simply only allow them edit the ones that belongs
to them.
Assume:
Item has_many :users
def update
@item = Item.find(params[:id])
if @item.user == session[:user]
@item.update_attributes(params[:item])
redirect_to :action => 'show', :id => @item
else
render :text => 'Hacker!'
end
end
#1 line less
def update
if @item = current_user.items.find_by_id(params[:id])
@item.update_attributes(params[:item])
redirect_to :action => 'show', :id => @item
else
render :text => 'Hacker!'
end
end
Gokhan
www.sylow.net