class Brakeman::CheckDeserialize

Public Instance Methods

check_csv() click to toggle source
# File lib/brakeman/checks/check_deserialize.rb, line 35
def check_csv
  check_methods :CSV, :load
end
check_deserialize(result, target, arg = nil) click to toggle source
# File lib/brakeman/checks/check_deserialize.rb, line 69
def check_deserialize result, target, arg = nil
  return unless original? result

  arg ||= result[:call].first_arg
  method = result[:call].method

  if input = has_immediate_user_input?(arg)
    confidence = :high
  elsif input = include_user_input?(arg)
    confidence = :medium
  end

  if confidence
    message = msg(msg_code("#{target}.#{method}"), " called with ", msg_input(input))

    warn :result => result,
      :warning_type => "Remote Code Execution",
      :warning_code => :unsafe_deserialize,
      :message => message,
      :user_input => input,
      :confidence => confidence,
      :link_path => "unsafe_deserialization",
      :cwe_id => [502]
  end
end
check_marshal() click to toggle source
# File lib/brakeman/checks/check_deserialize.rb, line 39
def check_marshal
  check_methods :Marshal, :load, :restore
end
check_methods(target, *methods) click to toggle source
# File lib/brakeman/checks/check_deserialize.rb, line 63
def check_methods target, *methods
  tracker.find_call(:target => target, :methods => methods ).each do |result|
    check_deserialize result, target
  end
end
check_oj() click to toggle source
# File lib/brakeman/checks/check_deserialize.rb, line 43
def check_oj
  check_methods :Oj, :object_load # Always unsafe, regardless of mode

  unsafe_mode = :object
  safe_default = oj_safe_default?

  tracker.find_call(:target => :Oj, :method => :load).each do |result|
    call = result[:call]
    options = call.second_arg

    if options and hash? options and mode = hash_access(options, :mode)
      if symbol? mode and mode.value == unsafe_mode
        check_deserialize result, :Oj
      end
    elsif not safe_default
      check_deserialize result, :Oj
    end
  end
end
check_yaml() click to toggle source
# File lib/brakeman/checks/check_deserialize.rb, line 15
def check_yaml
  check_methods :YAML, :load_documents, :load_stream, :parse_documents, :parse_stream

  # Check for safe_yaml gem use with YAML.load(..., safe: true)
  if uses_safe_yaml?
    tracker.find_call(target: :YAML, method: :load).each do |result|
      call = result[:call]
      options = call.second_arg

      if hash? options and true? hash_access(options, :safe)
        next
      else
        check_deserialize result, :YAML
      end
    end
  else
    check_methods :YAML, :load
  end
end
run_check() click to toggle source
# File lib/brakeman/checks/check_deserialize.rb, line 8
def run_check
  check_yaml
  check_csv
  check_marshal
  check_oj
end

Private Instance Methods

oj_safe_default?() click to toggle source
# File lib/brakeman/checks/check_deserialize.rb, line 97
def oj_safe_default?
  safe_default = false

  if tracker.find_call(target: :Oj, method: :mimic_JSON).any?
    safe_default = true
  elsif result = tracker.find_call(target: :Oj, method: :default_options=).first
    options = result[:call].first_arg

    if oj_safe_mode? options
      safe_default = true
    end
  end

  safe_default
end
oj_safe_mode?(options) click to toggle source
# File lib/brakeman/checks/check_deserialize.rb, line 113
def oj_safe_mode? options
  if hash? options and mode = hash_access(options, :mode)
    if symbol? mode and mode != :object
      return true
    end
  end

  false
end
uses_safe_yaml?() click to toggle source
# File lib/brakeman/checks/check_deserialize.rb, line 123
def uses_safe_yaml?
  tracker.config.has_gem? :safe_yaml
end