Wolfmans Howlings

A programmers Blog about Ruby, Rails and a few other issues

REST scaffold_resource security warning

Posted by Jim Morris Tue, 26 Jun 2007 22:14:04 GMT

This one is so blatantly obvious it bit me in the Butt at 4am this morning when I had to get up and fix it! I am so embarrassed, luckily no private data got out, as no-one has entered any private data yet.

I used the script/generate scaffold_resource to get started, and I left in those nice format.xml things in, thinking I may use them in the future. For the most part this is not a problem, but one of my controllers is a profile table. Much of the data in there is public anyway so no big deal, but a few columns are private data like email, date of birth, phone numbers etc. These are specifically private and not viewable publicly. This is enforced but not having a view that shows any of that stuff to the general public.

However the tricky little scaffold-generated code...

  def index
    @profiles = Profile.find(:all, :order => "first_name, last_name, alias")

    respond_to do |format|
      format.html # index.rhtml
      format.xml  { render :xml => @profiles.to_xml }
     end
  end

Has this cool .to_xml stanza, which happily takes every column and converts it to XML and sends it back as a response to the query /profiles.xml

Yikes, I woke up with a start when I realized that, and rushed to test it and yep it works as it is supposed to.

Obviously this is easy to fix, Just exclude the attributes you don't want shown:

@profiles.to_xml(:only => [:first_name, :last_name])

But it sure is a nasty back door if you forget!

Caveat Programmer!

Posted in  | Tags ,  | 4 comments | no trackbacks

Comments

  1. K. Adam Christensen said about 18 hours later:

    Nice catch! Time to go review some code.

  2. Evgeny said 18 days later:

    Actually, its probably better to fix that in the model, and not the controller. Using attr_accessible or attr_protected, or something similar - just close those columns for the general public and all your problems disappear. Besides, its the more "right" place for it anyways.

  3. wolfmanjm said 18 days later:

    AFAIK attr_protected and attr_accessible only protect against mass writes not reads, so that won't work in this case.

  4. Philip (flip) Kromer said 5 months later:

    Thanks for this -- I had the same realization, and now I can fix it.

    The other thing to set is filterparameterlogging, which controls what goes into your logs. (Logs should of course be outside the public purview, but 'Defense in Depth' is our creed.)

    If I understand correctly, attr_accessible controls data coming *in* -- it prevents someone setting an attribute by stuffing in a form value.

    Using the the restful-authentication generator as an example:

    • In the model file, blacklist fields from the logs: filterparameterlogging :password, :salt, "activation-code"

    • Also in the model, whitelist fields the user is allowed to set (this excludes things like confirmation code or usergroup): attraccessible :login, :email, :password, :passwordconfirmation

    • And, of course, in the controller file whitelist only the fields you wish to xml serialize: format.xml { render :xml => @user.toxml(:only => [:firstname, :last_name]) }

Trackbacks

Use the following link to trackback from your own site:
http://blog.wolfman.com/articles/trackback/323

(leave url/email »)

   Comment Markup Help Preview comment