class Brakeman::Config

Attributes

erubis[W]
escape_html[W]
gems[R]
rails[R]
ruby_version[R]
tracker[R]

Public Class Methods

new(tracker) click to toggle source
# File lib/brakeman/tracker/config.rb, line 10
def initialize tracker
  @tracker = tracker
  @rails = {}
  @gems = {}
  @settings = {}
  @escape_html = nil
  @erubis = nil
  @ruby_version = ""
  @rails_version = nil
end

Public Instance Methods

add_gem(name, version, file, line) click to toggle source
# File lib/brakeman/tracker/config.rb, line 60
def add_gem name, version, file, line
  name = name.to_sym
  @gems[name] = {
    :version => version,
    :file => file,
    :line => line
  }
end
default_protect_from_forgery?() click to toggle source
# File lib/brakeman/tracker/config.rb, line 21
def default_protect_from_forgery?
  if version_between? "5.2.0.beta1", "9.9.9"
    if @rails.dig(:action_controller, :default_protect_from_forgery) == Sexp.new(:false)
      return false
    else
      return true
    end
  end

  false
end
erubis?() click to toggle source
# File lib/brakeman/tracker/config.rb, line 33
def erubis?
  @erubis
end
escape_filter_interpolations?() click to toggle source
# File lib/brakeman/tracker/config.rb, line 46
def escape_filter_interpolations?
  # TODO see if app is actually turning this off itself
  has_gem?(:haml) and
    version_between? "5.0.0", "5.99", gem_version(:haml)
end
escape_html?() click to toggle source
# File lib/brakeman/tracker/config.rb, line 37
def escape_html?
  @escape_html
end
escape_html_entities_in_json?() click to toggle source
# File lib/brakeman/tracker/config.rb, line 41
def escape_html_entities_in_json?
  #TODO add version-specific information here
  true? @rails.dig(:active_support, :escape_html_entities_in_json)
end
extract_version(version) click to toggle source
# File lib/brakeman/tracker/config.rb, line 129
def extract_version version
  return unless version.is_a? String

  version[/\d+\.\d+(\.\d+.*)?/]
end
gem_version(name) click to toggle source
# File lib/brakeman/tracker/config.rb, line 56
def gem_version name
  extract_version @gems.dig(name.to_sym, :version)
end
get_gem(name) click to toggle source
# File lib/brakeman/tracker/config.rb, line 73
def get_gem name
  @gems[name.to_sym]
end
has_gem?(name) click to toggle source
# File lib/brakeman/tracker/config.rb, line 69
def has_gem? name
  !!@gems[name.to_sym]
end
load_rails_defaults() click to toggle source

Load defaults based on config.load_defaults value as documented here: guides.rubyonrails.org/configuring.html#results-of-config-load-defaults

# File lib/brakeman/tracker/config.rb, line 183
def load_rails_defaults
  return unless number? tracker.config.rails[:load_defaults]

  version = tracker.config.rails[:load_defaults].value
  true_value = Sexp.new(:true)
  false_value = Sexp.new(:false)

  if version >= 5.0
    set_rails_config(true_value, :action_controller, :per_form_csrf_tokens)
    set_rails_config(true_value, :action_controller, :forgery_protection_origin_check)
    set_rails_config(true_value, :active_record, :belongs_to_required_by_default)
    # Note: this may need to be changed, because ssl_options is a Hash
    set_rails_config(true_value, :ssl_options, :hsts, :subdomains)
  end

  if version >= 5.1
    set_rails_config(false_value, :assets, :unknown_asset_fallback)
    set_rails_config(true_value, :action_view, :form_with_generates_remote_forms)
  end

  if version >= 5.2
    set_rails_config(true_value, :active_record, :cache_versioning)
    set_rails_config(true_value, :action_dispatch, :use_authenticated_cookie_encryption)
    set_rails_config(true_value, :active_support, :use_authenticated_message_encryption)
    set_rails_config(true_value, :active_support, :use_sha1_digests)
    set_rails_config(true_value, :action_controller, :default_protect_from_forgery)
    set_rails_config(true_value, :action_view, :form_with_generates_ids)
  end

  if version >= 6.0
    set_rails_config(Sexp.new(:lit, :zeitwerk), :autoloader)
    set_rails_config(false_value, :action_view, :default_enforce_utf8)
    set_rails_config(true_value, :action_dispatch, :use_cookies_with_metadata)
    set_rails_config(false_value, :action_dispatch, :return_only_media_type_on_content_type)
    set_rails_config(Sexp.new(:str, 'ActionMailer::MailDeliveryJob'), :action_mailer, :delivery_job)
    set_rails_config(true_value, :active_job, :return_false_on_aborted_enqueue)
    set_rails_config(Sexp.new(:lit, :active_storage_analysis), :active_storage, :queues, :analysis)
    set_rails_config(Sexp.new(:lit, :active_storage_purge), :active_storage, :queues, :purge)
    set_rails_config(true_value, :active_storage, :replace_on_assign_to_many)
    set_rails_config(true_value, :active_record, :collection_cache_versioning)
  end
end
rails_version() click to toggle source
# File lib/brakeman/tracker/config.rb, line 119
def rails_version
  # This needs to be here because Util#rails_version calls Tracker::Config#rails_version
  # but Tracker::Config includes Util...
  @rails_version
end
session_settings() click to toggle source
# File lib/brakeman/tracker/config.rb, line 149
def session_settings
  @rails.dig(:action_controller, :session)
end
set_rails_config(value, *path) click to toggle source

Set Rails config option value where path is an array of attributes, e.g.

:action_controller, :perform_caching

then this will set

rails[:action_controller][:perform_caching] = value
# File lib/brakeman/tracker/config.rb, line 162
def set_rails_config value, *path
  config = self.rails

  path[0..-2].each do |o|
    config[o] ||= {}

    option = config[o]

    if not option.is_a? Hash
      Brakeman.debug "[Notice] Skipping config setting: #{path.map(&:to_s).join(".")}"
      return
    end

    config = option
  end

  config[path.last] = value
end
set_rails_version(version = nil) click to toggle source
# File lib/brakeman/tracker/config.rb, line 77
def set_rails_version version = nil
  version = if version
              # Only used by Rails2ConfigProcessor right now
              extract_version(version)
            else
              gem_version(:rails) ||
                gem_version(:railties) ||
                gem_version(:activerecord)
            end

  if version
    @rails_version = version

    if tracker.options[:rails3].nil? and tracker.options[:rails4].nil?
      if @rails_version.start_with? "3"
        tracker.options[:rails3] = true
        Brakeman.notify "[Notice] Detected Rails 3 application"
      elsif @rails_version.start_with? "4"
        tracker.options[:rails3] = true
        tracker.options[:rails4] = true
        Brakeman.notify "[Notice] Detected Rails 4 application"
      elsif @rails_version.start_with? "5"
        tracker.options[:rails3] = true
        tracker.options[:rails4] = true
        tracker.options[:rails5] = true
        Brakeman.notify "[Notice] Detected Rails 5 application"
      elsif @rails_version.start_with? "6"
        tracker.options[:rails3] = true
        tracker.options[:rails4] = true
        tracker.options[:rails5] = true
        tracker.options[:rails6] = true
        Brakeman.notify "[Notice] Detected Rails 6 application"
      end
    end
  end

  if get_gem :rails_xss
    @escape_html = true
    Brakeman.notify "[Notice] Escaping HTML by default"
  end
end
set_ruby_version(version) click to toggle source
# File lib/brakeman/tracker/config.rb, line 125
def set_ruby_version version
  @ruby_version = extract_version(version)
end
version_between?(low_version, high_version, current_version = nil) click to toggle source

Returns true if low_version <= RAILS_VERSION <= high_version

If the Rails version is unknown, returns false.

# File lib/brakeman/tracker/config.rb, line 138
def version_between? low_version, high_version, current_version = nil
  current_version ||= rails_version
  return false unless current_version

  low = Gem::Version.new(low_version)
  high = Gem::Version.new(high_version)
  current = Gem::Version.new(current_version)

  current.between?(low, high)
end
whitelist_attributes?() click to toggle source
# File lib/brakeman/tracker/config.rb, line 52
def whitelist_attributes?
  @rails.dig(:active_record, :whitelist_attributes) == Sexp.new(:true)
end