#Processes configuration. Results are put in tracker.config. # #Configuration of Rails via Rails::Initializer are stored in tracker.config[:rails]. #For example: # # MyApp::Application.configure do # config.active_record.whitelist_attributes = true # end # #will be stored in # # tracker.config[:rails][:active_record][:whitelist_attributes] # #Values for tracker.config[:rails] will still be Sexps. class Brakeman::Rails3ConfigProcessor < Brakeman::BaseProcessor RAILS_CONFIG = Sexp.new(:call, nil, :config) def initialize *args super @tracker.config[:rails] ||= {} @inside_config = false end #Use this method to process configuration file def process_config src res = Brakeman::AliasProcessor.new(@tracker).process_safely(src) process res end #Look for MyApp::Application.configure do ... end def process_iter exp if node_type?(exp.block_call.target, :colon2) and exp.block_call.method == :Application @inside_config = true process_all exp.body if sexp? exp.body @inside_config = false end exp end #Look for class Application < Rails::Application def process_class exp if exp.class_name == :Application @inside_config = true process_all exp.body if sexp? exp.body @inside_config = false end exp end #Look for configuration settings def process_attrasgn exp return exp unless @inside_config if exp.target == RAILS_CONFIG #Get rid of '=' at end attribute = exp.method.to_s[0..-2].to_sym if exp.args.length > 1 #Multiple arguments?...not sure if this will ever happen @tracker.config[:rails][attribute] = exp.args else @tracker.config[:rails][attribute] = exp.first_arg end elsif include_rails_config? exp options = get_rails_config exp level = @tracker.config[:rails] options[0..-2].each do |o| level[o] ||= {} level = level[o] end level[options.last] = exp.first_arg end exp end #Check if an expression includes a call to set Rails config def include_rails_config? exp target = exp.target if call? target if target.target == RAILS_CONFIG true else include_rails_config? target end elsif target == RAILS_CONFIG true else false end end #Returns an array of symbols for each 'level' in the config # # config.action_controller.session_store = :cookie # #becomes # # [:action_controller, :session_store] def get_rails_config exp if node_type? exp, :attrasgn attribute = exp.method.to_s[0..-2].to_sym get_rails_config(exp.target) << attribute elsif call? exp if exp.target == RAILS_CONFIG [exp.method] else get_rails_config(exp.target) << exp.method end else raise "WHAT" end end end