class Railroader::CheckSessionSettings

Checks for session key length and http_only settings

Public Class Methods

new(*args) click to toggle source
Calls superclass method Railroader::BaseCheck::new
# File lib/railroader/checks/check_session_settings.rb, line 9
def initialize *args
  super

  unless tracker.options[:rails3]
    @session_settings = Sexp.new(:colon2, Sexp.new(:const, :ActionController), :Base)
  else
    @session_settings = nil
  end
end

Public Instance Methods

process_attrasgn(exp) click to toggle source

Looks for ActionController::Base.session = { … } in Rails 2.x apps

and App::Application.config.secret_token = in Rails 3.x apps

and App::Application.config.secret_key_base = in Rails 4.x apps

# File lib/railroader/checks/check_session_settings.rb, line 43
def process_attrasgn exp
  if not tracker.options[:rails3] and exp.target == @session_settings and exp.method == :session=
    check_for_issues exp.first_arg, @app_tree.expand_path("config/initializers/session_store.rb")
  end

  if tracker.options[:rails3] and settings_target?(exp.target) and
    (exp.method == :secret_token= or exp.method == :secret_key_base=) and string? exp.first_arg

    warn_about_secret_token exp.line, @app_tree.expand_path("config/initializers/secret_token.rb")
  end

  exp
end
process_call(exp) click to toggle source

Looks for Rails3::Application.config.session_store :cookie_store, { … } in Rails 3.x apps

# File lib/railroader/checks/check_session_settings.rb, line 59
def process_call exp
  if tracker.options[:rails3] and settings_target?(exp.target) and exp.method == :session_store
    check_for_rails3_issues exp.second_arg, @app_tree.expand_path("config/initializers/session_store.rb")
  end

  exp
end
run_check() click to toggle source
# File lib/railroader/checks/check_session_settings.rb, line 19
def run_check
  settings = tracker.config.session_settings

  check_for_issues settings, @app_tree.expand_path("config/environment.rb")

  ["session_store.rb", "secret_token.rb"].each do |file|
    if tracker.initializers[file] and not ignored? file
      process tracker.initializers[file]
    end
  end

  if tracker.options[:rails4]
    check_secrets_yaml
  end
end

Private Instance Methods

check_for_issues(settings, file) click to toggle source
# File lib/railroader/checks/check_session_settings.rb, line 76
def check_for_issues settings, file
  if settings and hash? settings
    if value = (hash_access(settings, :session_http_only) ||
                hash_access(settings, :http_only) ||
                hash_access(settings, :httponly))

      if false? value
        warn_about_http_only value.line, file
      end
    end

    if value = hash_access(settings, :secret)
      if string? value
        warn_about_secret_token value.line, file
      end
    end
  end
end
check_for_rails3_issues(settings, file) click to toggle source
# File lib/railroader/checks/check_session_settings.rb, line 95
def check_for_rails3_issues settings, file
  if settings and hash? settings
    if value = hash_access(settings, :httponly)
      if false? value
        warn_about_http_only value.line, file
      end
    end

    if value = hash_access(settings, :secure)
      if false? value
        warn_about_secure_only value.line, file
      end
    end
  end
end
check_secrets_yaml() click to toggle source
# File lib/railroader/checks/check_session_settings.rb, line 111
def check_secrets_yaml
  secrets_file = "config/secrets.yml"

  if @app_tree.exists? secrets_file and not ignored? "secrets.yml" and not ignored? "config/*.yml"
    yaml = @app_tree.read secrets_file
    require 'date' # https://github.com/dtao/safe_yaml/issues/80
    require 'safe_yaml/load'
    begin
      secrets = SafeYAML.load yaml
    rescue Psych::SyntaxError, RuntimeError => e
      Railroader.notify "[Notice] #{self.class}: Unable to parse `#{secrets_file}`"
      Railroader.debug "Failed to parse #{secrets_file}: #{e.inspect}"
      return
    end

    if secrets["production"] and secret = secrets["production"]["secret_key_base"]
      unless secret.include? "<%="
        line = yaml.lines.find_index { |l| l.include? secret } + 1

        warn_about_secret_token line, @app_tree.expand_path(secrets_file)
      end
    end
  end
end
ignored?(file) click to toggle source
# File lib/railroader/checks/check_session_settings.rb, line 164
def ignored? file
  [".", "config", "config/initializers"].each do |dir|
    ignore_file = "#{dir}/.gitignore"
    if @app_tree.exists? ignore_file
      input = @app_tree.read(ignore_file)

      return true if input.include? file
    end
  end

  false
end
settings_target?(exp) click to toggle source
# File lib/railroader/checks/check_session_settings.rb, line 69
def settings_target? exp
  call? exp and
  exp.method == :config and
  node_type? exp.target, :colon2 and
  exp.target.rhs == :Application
end
warn_about_http_only(line, file) click to toggle source
# File lib/railroader/checks/check_session_settings.rb, line 136
def warn_about_http_only line, file
  warn :warning_type => "Session Setting",
    :warning_code => :http_cookies,
    :message => "Session cookies should be set to HTTP only",
    :confidence => :high,
    :line => line,
    :file => file

end
warn_about_secret_token(line, file) click to toggle source
# File lib/railroader/checks/check_session_settings.rb, line 146
def warn_about_secret_token line, file
  warn :warning_type => "Session Setting",
    :warning_code => :session_secret,
    :message => "Session secret should not be included in version control",
    :confidence => :high,
    :line => line,
    :file => file
end
warn_about_secure_only(line, file) click to toggle source
# File lib/railroader/checks/check_session_settings.rb, line 155
def warn_about_secure_only line, file
  warn :warning_type => "Session Setting",
    :warning_code => :secure_cookies,
    :message => "Session cookie should be set to secure only",
    :confidence => :high,
    :line => line,
    :file => file
end