Class: Brakeman::CheckExecute

Inherits:
BaseCheck show all
Defined in:
lib/brakeman/checks/check_execute.rb

Overview

Checks for string interpolation and parameters in calls to Kernel#system, Kernel#exec, Kernel#syscall, and inside backticks.

Examples of command injection vulnerabilities:

system(“rf -rf #:file”) exec(params) ‘unlink #params[:something`

Constant Summary

Constants inherited from BaseCheck

BaseCheck::CONFIDENCE

Constants included from Util

Util::ALL_PARAMETERS, Util::COOKIES, Util::PARAMETERS, Util::PATH_PARAMETERS, Util::QUERY_PARAMETERS, Util::REQUEST_ENV, Util::REQUEST_PARAMETERS, Util::REQUEST_PARAMS, Util::SESSION

Constants inherited from SexpProcessor

SexpProcessor::VERSION

Instance Attribute Summary

Attributes inherited from BaseCheck

#tracker, #warnings

Attributes inherited from SexpProcessor

#context, #env, #expected

Instance Method Summary collapse

Methods inherited from BaseCheck

#add_result, #initialize, #process_call, #process_cookies, #process_default, #process_if, #process_params

Methods included from Util

#array?, #call?, #camelize, #contains_class?, #context_for, #cookies?, #false?, #file_by_name, #file_for, #hash?, #hash_access, #hash_insert, #hash_iterate, #integer?, #node_type?, #number?, #params?, #pluralize, #regexp?, #request_env?, #request_value?, #result?, #set_env_defaults, #sexp?, #string?, #symbol?, #table_to_csv, #true?, #truncate_table, #underscore

Methods included from ProcessorHelper

#class_name, #process_all, #process_module

Methods inherited from SexpProcessor

#error_handler, #in_context, #initialize, #process, #process_dummy, #scope

Constructor Details

This class inherits a constructor from Brakeman::BaseCheck

Instance Method Details

#check_for_backticks(tracker) ⇒ Object

Looks for calls using backticks such as

‘rm -rf #:file`



64
65
66
67
68
# File 'lib/brakeman/checks/check_execute.rb', line 64

def check_for_backticks tracker
  tracker.find_call(:target => nil, :method => :`).each do |result|
    process_backticks result
  end
end

#process_backticks(result) ⇒ Object

Processes backticks.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/brakeman/checks/check_execute.rb', line 71

def process_backticks result
  return if duplicate? result

  add_result result

  exp = result[:call]

  if input = include_user_input?(exp)
    confidence = CONFIDENCE[:high]
    user_input = input.match
  else
    confidence = CONFIDENCE[:med]
    user_input = nil
  end

  warning = { :warning_type => "Command Injection",
    :message => "Possible command injection",
    :code => exp,
    :user_input => user_input,
    :confidence => confidence }

  if result[:location][0] == :template
    warning[:template] = result[:location][1]
  else
    warning[:class] = result[:location][1]
    warning[:method] = result[:location][2]
  end

  warn warning
end

#process_result(result) ⇒ Object

Processes results from Tracker#find_call.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/brakeman/checks/check_execute.rb', line 31

def process_result result
  call = result[:call]

  args = process call[3]

  case call.method
  when :system, :exec
    failure = include_user_input?(args[1]) || include_interp?(args[1])
  else
    failure = include_user_input?(args) || include_interp?(args)
  end

  if failure and not duplicate? result
    add_result result

    if @string_interp
      confidence = CONFIDENCE[:med]
    else
      confidence = CONFIDENCE[:high]
    end

    warn :result => result,
      :warning_type => "Command Injection", 
      :message => "Possible command injection",
      :code => call,
      :user_input => failure.match,
      :confidence => confidence
  end
end

#run_checkObject

Check models, controllers, and views for command injection.



17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/brakeman/checks/check_execute.rb', line 17

def run_check
  Brakeman.debug "Finding system calls using ``"
  check_for_backticks tracker

  Brakeman.debug "Finding other system calls"
  calls = tracker.find_call :targets => [:IO, :Open3, :Kernel, nil], :methods => [:exec, :popen, :popen3, :syscall, :system]

  Brakeman.debug "Processing system calls"
  calls.each do |result|
    process_result result
  end
end