Changeset 156

Show
Ignore:
Timestamp:
02/11/08 20:38:28 (7 months ago)
Author:
stu
Message:

working with activerecord

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • incubator/sentinel/init.rb

    r155 r156  
    11# Include hook code here 
     2require 'relevance/sentinel' 
  • incubator/sentinel/lib/relevance/sentinel/active_record.rb

    r155 r156  
    22  def self.sanitize_all_finds 
    33    ActiveRecord::Base.class_eval do 
    4       include Relevance::Sentinel::ActiveRecord 
    5       alias_method_chain :find, :sentinel_sanitize 
    6       def sentinel_sanitize(*args, &blk) 
    7         args.last = Relevance::Sentinel::ActiveRecord.sanitize_find_options(args.last) if Hash === args.last 
    8         find_without_sentinel_sanitize(*args, &blk) 
     4      extend Relevance::Sentinel::ActiveRecord 
     5      class << self 
     6        def find_with_sentinel_sanitize(*args, &blk) 
     7          args.push(sanitize_find_options!(args.pop)) if Hash === args.last 
     8          find_without_sentinel_sanitize(*args, &blk) 
     9        end 
     10        alias_method_chain :find, :sentinel_sanitize 
    911      end 
    1012    end 
  • incubator/sentinel/README

    r155 r156  
    1 Sentinel 
    2 ======== 
     1Sentinel 0.1 
     2============ 
    33 
    4 Introduction goes here. 
     4Rails programmers know to be careful with :conditions clauses to avoid  
     5SQL injection attacks. For example: 
     6 
     7# Bad: 
     8find(:first, :conditions => "user_name = '#{user_name}' AND password = '#{password}'") 
     9# Better: 
     10find(:first, :conditions => { :user_name => user_name, :password => password }) 
     11 
     12However, there is a lot of code that gives less care to the other options on 
     13ActiveRecord::Base#find. For example, consider the following misuses of ":limit": 
     14 
     15Asset.find(:all, :limit => "10 into outfile '/tmp/outfile'") 
     16Asset.find(:all, :limit => "10 procedure someproc()")  
     17 
     18You probably don't want users to be able to create files on the server or  
     19execute arbitrary stored procedures! Sentinel aims to prevent these misuses. 
     20 
     21Usage 
     22============ 
     23 
     24There are two ways to use Sentinel: 
     25 
     261. You can mix in Relevance::Sentinel::ActiveRecord and call  
     27   sanitize_find_options! on an options hash before passing it to ActiveRecord. 
     28    
     292. You can activate Sentinel for all finds by calling 
     30      Relevance::Sentinel::ActiveRecord.sanitize_all_finds 
     31   If you rely on passing complex SQL to find options, this option may 
     32   not work for you, as Sentinel may reject some complex (but safe) SQL.     
     33 
     34Warning! 
     35============ 
     36Sentinel is not production ready. At this time it is probably broken in  
     37both directions, i.e. 
     38 
     39* Sentinel may allow accept some bad inputs 
     40* Sentinel may reject some good inputs 
     41 
     42Sentinel is under active development. If you have a case that is not covered, 
     43please contribute a patch or at least a broken test to stu@thinkrelevance.com. 
    544 
    645 
    7 Example 
    8 ======= 
     46TODO 
     47============ 
     48* cover every possible option to ActiveRecord::Base#find. 
     49* investigate patching ActiveRecord at a different level than find 
     50* should sanitization throw exceptions, neuter bad data, or some of both? 
     51* test other databases 
    952 
    10 Example goes here. 
    11  
    12  
    13 Copyright (c) 2008 [name of plugin creator], released under the MIT license 
     53Copyright (c) 2008 Relevance, Inc., released under the MIT license 
  • incubator/sentinel/test/relevance/sentinel/active_record_test.rb

    r155 r156  
    3535end 
    3636 
     37Relevance::Sentinel::ActiveRecord.sanitize_all_finds 
     38 
     39describe "ActiveRecord find method" do 
     40  # this test might behave different for other db layers than MySQL... 
     41  it "does not sanitize :limit" do 
     42    lambda { 
     43      Person.find_without_sentinel_sanitize(:all, :limit => "invalid value") 
     44    }.should.raise(ActiveRecord::StatementInvalid) 
     45  end 
     46end 
     47 
    3748describe "Relevance::Sentinel::ActiveRecord ActiveRecord integration" do 
     49  it "protects all finds" do 
     50    lambda { 
     51      Person.find_with_sentinel_sanitize(:all, :limit => "invalid value") 
     52    }.should.raise(ArgumentError) 
     53  end 
    3854   
     55  it "delegates through to find" do 
     56    Person.expects(:find_without_sentinel_sanitize).with(:all, :limit => 10) 
     57    Person.find_with_sentinel_sanitize(:all, :limit => 10) 
     58  end 
    3959end 
  • incubator/sentinel/test/relevance/sentinel_test.rb

    r155 r156  
    11require File.join(File.dirname(__FILE__), "..", "test_helper.rb") 
    22 
    3 describe "Relevance::Sentinel" do 
    4  
    5 end 
  • incubator/sentinel/test/test_helper.rb

    r155 r156  
    55require 'mocha' 
    66require 'ruby-debug' 
    7 require 'relevance/sentinel' 
    87 
    98gem 'activerecord' 
    109require 'active_record' 
    11  
    12 db_config_file = File.join(File.dirname(__FILE__) + '/config/database.yml') 
     10db_config_file = File.join(basedir + '/config/database.yml') 
    1311ActiveRecord::Base.configurations = YAML.load_file(db_config_file) 
    1412ActiveRecord::Base.establish_connection('sentinel_test') 
     13require File.join(basedir, "fixtures/schema.rb") 
    1514 
     15require 'relevance/sentinel'