Blogging from Inside the New Media Revolution

Smibs on Code: Filtering user data II

No Comments Yet
By Forrest - May 28th, 2009

In my last post for “Smibs on Code” I discussed the tradeoffs between pre-filtering and post-filtering user data in a web application. I also mentioned that Rails is focused on the post-filter approach, while I prefer pre-filtering. This week I’ll show you a plug-in we put together to perform the filtering for our Smibs Network and Doorbell.

This plug-in relies on a second smaller plug-in I wrote, which extends the String class. One of the functions added is ‘filter’. It escapes all dangerous characters. An example would be replacing all ‘<‘ characters (which can be used to run javascript code) with ‘&#60;’ which the browser will display as a ‘<‘, but is no longer dangerous.

The main plug-in extends the ActiveRecord class. This adds a function called apply_filter_on which is used to specify which fields you wish to filter, and a before_validation function which will be used to filter the user inputs when saving, but before the validations are run.

module ModelLevelSecurity
  def self.included(mod)
    mod.extend(ClassMethods)
    mod.before_validation(:apply_filter_now)
  end
 
  module ClassMethods
    def apply_filter_on(*var_names)
      write_inheritable_array(:filter_applies_on, var_names)
    end
  end
 
  private
 
  def apply_filter_now
    var_names = (self.class.read_inheritable_attribute(:filter_applies_on) || [])
    var_names.each{|var_name|
      unless read_attribute(var_name).blank?
        write_attribute(var_name,read_attribute(var_name).to_s.filter)
      end
    }
  end
end

This lets me specify which data fields should be filtered. Obviously, only the strings need to be filtered. Integers can’t really be hacked to the same level (NOTE: You still have to escape the SQL, but this is done separately). In the model I can specify the data fields with:

class Person &lt; ActiveRecord::Base
  ...
  attr_accessible :fname, :lname, :salut, :byear, :bmonth, :bday,
  apply_filter_on :fname, :lname, :salut
  ...
end

As I said before, there are many ways of solving this problem, and you may disagree with me on the best location to place the filter. Hopefully this helps some developers, who like me, felt that it was better to play it safe and escape when you grab the data from the user, rather than the alternative.

Filed under: Smibs Inc.  •  Tagged:

Leave comment

NOTE: We’d rather not moderate, but inappropropriate comments may be removed. Repeat offenders will be banned from commenting. Now, let’s focus on adding fun and valuable content. Thank you