Skip to content

Commit

Permalink
enable filtering of sensitive Rack vars by default
Browse files Browse the repository at this point in the history
see #185 for more details
  • Loading branch information
shime committed Nov 12, 2013
1 parent 6544885 commit c9098b1
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 9 deletions.
14 changes: 14 additions & 0 deletions features/rails.feature
Expand Up @@ -150,6 +150,20 @@ Feature: Install the Gem in a Rails application
And the Airbrake notification should not contain "blue42" And the Airbrake notification should not contain "blue42"
And the Airbrake notification should contain "FILTERED" And the Airbrake notification should contain "FILTERED"


Scenario: Filtering sensitive Rack variables
When I configure the Airbrake shim
And I run `rails generate airbrake -k myapikey -t`
When I configure the notifier to use the following configuration lines:
"""
config.logger = Logger.new STDOUT
"""
And I define a response for "TestController#index":
"""
raise RuntimeError
"""
Then I should receive a Airbrake notification
And the Airbrake notification should not contain any of the sensitive Rack variables

Scenario: Notify airbrake within the controller Scenario: Notify airbrake within the controller
When I configure the Airbrake shim When I configure the Airbrake shim
And I run `rails generate airbrake -k myapikey -t` And I run `rails generate airbrake -k myapikey -t`
Expand Down
8 changes: 7 additions & 1 deletion features/step_definitions/rails_application_steps.rb
Expand Up @@ -253,6 +253,13 @@ def #{current_user}
step %{the last notice sent should contain "<id>1</id>"} step %{the last notice sent should contain "<id>1</id>"}
end end


Then /^the Airbrake notification should not contain any of the sensitive Rack variables$/ do
sensitive_rack_data_regex = FILTERED_RACK_VARS.map do |var|
Regexp.quote(var)
end.join("|")
step %{the last notice sent should not contain "#{sensitive_rack_data_regex}"}
end

Then /^the last notice sent should contain "([^\"]*)"$/ do |data| Then /^the last notice sent should contain "([^\"]*)"$/ do |data|
last_notice = File.read(LAST_NOTICE) last_notice = File.read(LAST_NOTICE)
last_notice.should match(%r{#{data}}) last_notice.should match(%r{#{data}})
Expand All @@ -263,7 +270,6 @@ def #{current_user}
last_notice.should_not match(%r{#{data}}) last_notice.should_not match(%r{#{data}})
end end



Then /^the Airbrake notification should contain the framework information$/ do Then /^the Airbrake notification should contain the framework information$/ do
step %{the last notice sent should contain "Rails: #{ENV["RAILS_VERSION"]}"} step %{the last notice sent should contain "Rails: #{ENV["RAILS_VERSION"]}"}
end end
Expand Down
24 changes: 18 additions & 6 deletions features/support/env.rb
@@ -1,16 +1,20 @@
require 'active_support' require 'active_support'
require 'nokogiri' require 'nokogiri'
require 'rspec' require 'rspec'
require "aruba/cucumber" require 'aruba/cucumber'
require 'pry'


PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..')).freeze PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..')).freeze
TEMP_DIR = File.join(PROJECT_ROOT, 'tmp').freeze TEMP_DIR = File.join(PROJECT_ROOT, 'tmp').freeze
LOCAL_RAILS_ROOT = File.join(TEMP_DIR, 'rails_root').freeze LOCAL_RAILS_ROOT = File.join(TEMP_DIR, 'rails_root').freeze
RACK_FILE = File.join(TEMP_DIR, 'rack_app.rb').freeze RACK_FILE = File.join(TEMP_DIR, 'rack_app.rb').freeze
LAST_NOTICE = File.join(PROJECT_ROOT, 'resources', 'notice.xml') LAST_NOTICE = File.join(PROJECT_ROOT, 'resources', 'notice.xml')
ORIGINAL_RACK_FILTERS = File.join(PROJECT_ROOT, 'lib', 'airbrake', 'utils', 'rack_filters.rb')


Before do Before do
FileUtils.rm_rf(LOCAL_RAILS_ROOT) FileUtils.rm_rf(LOCAL_RAILS_ROOT)

reload_rack_filters
end end


When /^I reset Bundler environment variable$/ do When /^I reset Bundler environment variable$/ do
Expand All @@ -23,3 +27,11 @@ def prepend_path(path)
ENV['PATH'] = path + ":" + ENV['PATH'] ENV['PATH'] = path + ":" + ENV['PATH']
end end


def reload_rack_filters
original_filters = File.read(ORIGINAL_RACK_FILTERS)

File.write(File.join(TEMP_DIR, "rack_filters.rb"),
original_filters.lines[1..-2].join("\n"))

require File.join(TEMP_DIR, "rack_filters.rb")
end
1 change: 1 addition & 0 deletions lib/airbrake.rb
Expand Up @@ -9,6 +9,7 @@
require 'logger' require 'logger'


require 'airbrake/version' require 'airbrake/version'
require 'airbrake/utils/rack_filters'
require 'airbrake/utils/params_cleaner' require 'airbrake/utils/params_cleaner'
require 'airbrake/configuration' require 'airbrake/configuration'
require 'airbrake/notice' require 'airbrake/notice'
Expand Down
5 changes: 3 additions & 2 deletions lib/airbrake/utils/params_cleaner.rb
Expand Up @@ -55,8 +55,9 @@ def clean_session_data


def clean_rack_request_data def clean_rack_request_data
if @cgi_data if @cgi_data
@cgi_data.delete("rack.request.form_vars") Airbrake::FILTERED_RACK_VARS.each do |var|
@cgi_data.delete("action_dispatch.secret_token") @cgi_data.delete var
end
end end
end end


Expand Down
39 changes: 39 additions & 0 deletions lib/airbrake/utils/rack_filters.rb
@@ -0,0 +1,39 @@
module Airbrake
SENSITIVE_RACK_VARS = %w(
HTTP_X_CSRF_TOKEN
HTTP_COOKIE

action_dispatch.request.unsigned_session_cookie
action_dispatch.cookies
action_dispatch.unsigned_session_cookie
action_dispatch.secret_key_base
action_dispatch.signed_cookie_salt
action_dispatch.encrypted_cookie_salt
action_dispatch.encrypted_signed_cookie_salt
action_dispatch.http_auth_salt
action_dispatch.secret_token

rack.request.cookie_hash
rack.request.cookie_string
rack.request.form_vars

rack.session
rack.session.options
)

RACK_VARS_CONTAINING_INSTANCES = %w(
action_controller.instance

action_dispatch.backtrace_cleaner
action_dispatch.routes
action_dispatch.logger
action_dispatch.key_generator

rack-cache.storage

rack.errors
rack.input
)

FILTERED_RACK_VARS = SENSITIVE_RACK_VARS + RACK_VARS_CONTAINING_INSTANCES
end

0 comments on commit c9098b1

Please sign in to comment.