Storing URL in database -- h() or sanitize()?

Am I crazy?

It seems only smart to escape fields before they’re put into the
database if that is possible. If somebody injects SQL in their url or
first name where better to escape it than in the model before_save ?
Even attr_protected assumes that code is written to fix injection and
so on.

I ended up with this really irritating code:

include ActionView::Helpers::SanitizeHelper
HTML_ESCAPE    =    { '&' => '&', '"' => '"', '>' =>

‘>’, ‘<’ => ‘<’ }
def html_escape(s)
s.to_s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }
end

def before_save
  for c in [:lastname, :firstname, :login, :email]
    self[c] = html_escape(self[c])
    end
  self[:homepage] = sanitize(self[:homepage])
end

Several things:

  1. Maybe I should have used strip_tags.
  2. Is sanitize the right thing to use on a URL that will later be made
    into a link on a web page?
  3. Why the !@#$ do I have to search 4 or more places to find how to
    reference this code. Escaping is not sensibly restricted to the view,
    is it?
  4. And wouldn’t it be more sensible to be able to experiment with
    these routines in the console?

This is one of those places where the Rails framework seems terribly
unprofessional. I have three books and several web sites to search.
And not one of them told me the incantation to make this work in the
model. I shouldn’t have to be groveling around in the source code to
make simple things work.

I should be able to figure out correct code (at least the syntax) from
the documentation, or is that crazy?

F

If you’re using ActiveRecord for your ORM, it takes care of quoting
all your fields whenever you create or update. Furthermore, if you
use the standard find or it’s derivative find_by_xxx methods and let
it due substitution on the conditions then it quotes those values as
well. Both of these provisions are intended to prevent SQL injection
attacks and are fairly well publicized in Rails texts.

Similarly, the h (html_escape) method is usually one of the very first
ones you’re introduced to when you meet any explanation of Rails
views. It’s purpose, as the long name suggests, is to html escape
anything captured from a form so that it can be rendered without
destroying the page. If you want to use it in a view you simply
say…

<%= h my_object.some_field_with_user_data %>

That field will be neatly html-escaped for you.

Fred T. wrote:

Am I crazy?

It seems only smart to escape fields before they’re put into the
database if that is possible. If somebody injects SQL in their url or
first name where better to escape it than in the model before_save ?
Even attr_protected assumes that code is written to fix injection and
so on.

Sanitizing/escaping data before it enters the database is a valid way of
handling things. The reason it’s not usually recommended is you may
want to do things with the data other that just display it to the user.
However, if the only thing you are going to do with the data is display
it on a webpage, escaping the html before putting it in database may
work well. You do need to make sure that you aren’t also escaping it
when it is displayed.

I ended up with this really irritating code:

include ActionView::Helpers::SanitizeHelper
HTML_ESCAPE    =    { '&' => '&amp;', '"' => '&quot;', '>' =>

‘>’, ‘<’ => ‘<’ }
def html_escape(s)
s.to_s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }
end

def before_save
  for c in [:lastname, :firstname, :login, :email]
    self[c] = html_escape(self[c])
    end
  self[:homepage] = sanitize(self[:homepage])
end

You should probably use CGI for the html_escape[1]:

require ‘cgi’
CGI.escapeHTML(‘<“&”>’) # => “<"&">”

Several things:

  1. Maybe I should have used strip_tags.
  2. Is sanitize the right thing to use on a URL that will later be made
    into a link on a web page?
  3. Why the !@#$ do I have to search 4 or more places to find how to
    reference this code. Escaping is not sensibly restricted to the view,
    is it?
  4. And wouldn’t it be more sensible to be able to experiment with
    these routines in the console?

This is one of those places where the Rails framework seems terribly
unprofessional. I have three books and several web sites to search.
And not one of them told me the incantation to make this work in the
model. I shouldn’t have to be groveling around in the source code to
make simple things work.

If you want to know how things actually work in Rails, the source is
generally the best documentation (assuming you know ruby fairly well).
The reason you aren’t finding much information/documentation for what
you want to do is that you aren’t following standard Rails practice
(i.e. escape data on display, not on input).

I should be able to figure out correct code (at least the syntax) from
the documentation, or is that crazy?

It’s not crazy, just idealistic.

Jeremy

[1]
http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html#M000094