class Brakeman::CheckRender
Check calls to +render()+ for dangerous values
def check_for_dynamic_path result
def check_for_dynamic_path result view = result[:call][2] if sexp? view and original? result return if renderable?(view) if input = has_immediate_user_input?(view) if string_interp? view confidence = :medium else confidence = :high end else return end return if input.type == :model #skip models return if safe_param? input.match message = msg("Render path contains ", msg_input(input)) warn :result => result, :warning_type => "Dynamic Render Path", :warning_code => :dynamic_render_path, :message => message, :user_input => input, :confidence => confidence, :cwe_id => [22] end end
def known_renderable_class? class_name
def known_renderable_class? class_name klass = tracker.find_class(class_name) return false if klass.nil? knowns = [ :"ViewComponent::Base", :"ViewComponentContrib::Base", :"Phlex::HTML" ] knowns.any? { |k| klass.ancestor? k } end
def process_render_result result
def process_render_result result return unless node_type? result[:call], :render case result[:call].render_type when :partial, :template, :action, :file check_for_dynamic_path(result) when :inline when :js when :json when :text when :update when :xml end end
def renderable? exp
def renderable? exp return false unless call?(exp) and constant?(exp.target) if exp.method == :with_content exp = exp.target end return false unless constant?(exp.target) target_class_name = class_name(exp.target) known_renderable_class?(target_class_name) or tracker.find_method(:render_in, target_class_name) end
def run_check
def run_check tracker.find_call(:target => nil, :method => :render).each do |result| process_render_result result end end
def safe_param? exp
def safe_param? exp if params? exp and call? exp method_name = exp.method if method_name == :[] arg = exp.first_arg symbol? arg and [:controller, :action].include? arg.value else boolean_method? method_name end end end