tcell_agent 2.0.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +2 -2
- data/bin/tcell_agent +41 -150
- data/lib/tcell_agent/agent.rb +87 -52
- data/lib/tcell_agent/config_initializer.rb +63 -0
- data/lib/tcell_agent/configuration.rb +72 -267
- data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
- data/lib/tcell_agent/instrument_servers.rb +14 -18
- data/lib/tcell_agent/instrumentation/cmdi.rb +47 -15
- data/lib/tcell_agent/instrumentation/lfi.rb +72 -15
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/file.rb +21 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/io.rb +75 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/kernel.rb +80 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/file.rb +21 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/io.rb +75 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/kernel.rb +80 -0
- data/lib/tcell_agent/instrumentation.rb +14 -6
- data/lib/tcell_agent/logger.rb +3 -4
- data/lib/tcell_agent/policies/command_injection_policy.rb +1 -1
- data/lib/tcell_agent/policies/dataloss_policy.rb +15 -8
- data/lib/tcell_agent/policies/headers_policy.rb +2 -2
- data/lib/tcell_agent/policies/patches_policy.rb +8 -4
- data/lib/tcell_agent/policies/policies_manager.rb +1 -0
- data/lib/tcell_agent/policies/policy_polling.rb +4 -3
- data/lib/tcell_agent/rails/auth/authlogic.rb +49 -44
- data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
- data/lib/tcell_agent/rails/auth/devise.rb +103 -102
- data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +54 -57
- data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
- data/lib/tcell_agent/rails/better_ip.rb +7 -19
- data/lib/tcell_agent/rails/csrf_exception.rb +0 -8
- data/lib/tcell_agent/rails/dlp/process_request.rb +5 -0
- data/lib/tcell_agent/rails/dlp.rb +58 -56
- data/lib/tcell_agent/rails/dlp_handler.rb +9 -10
- data/lib/tcell_agent/rails/js_agent_insert.rb +2 -3
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -1
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +3 -4
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
- data/lib/tcell_agent/rails/{on_start.rb → railties/tcell_agent_railties.rb} +9 -16
- data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
- data/lib/tcell_agent/rails/routes/grape.rb +5 -12
- data/lib/tcell_agent/rails/routes.rb +6 -9
- data/lib/tcell_agent/rails/settings_reporter.rb +3 -6
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -7
- data/lib/tcell_agent/routes/table.rb +3 -0
- data/lib/tcell_agent/rust/agent_config.rb +62 -33
- data/lib/tcell_agent/rust/{libtcellagent-4.14.0.so → libtcellagent-alpine.so} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-4.14.0.dylib → libtcellagent-x64.dll} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-4.14.0.so → libtcellagent.dylib} +0 -0
- data/lib/tcell_agent/rust/libtcellagent.so +0 -0
- data/lib/tcell_agent/rust/models.rb +9 -0
- data/lib/tcell_agent/rust/native_agent.rb +61 -51
- data/lib/tcell_agent/rust/native_library.rb +8 -10
- data/lib/tcell_agent/sensor_events/server_agent.rb +3 -100
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +1 -0
- data/lib/tcell_agent/servers/puma.rb +30 -13
- data/lib/tcell_agent/servers/rack_puma_handler.rb +33 -0
- data/lib/tcell_agent/servers/rails_server.rb +4 -4
- data/lib/tcell_agent/servers/unicorn.rb +1 -1
- data/lib/tcell_agent/servers/webrick.rb +12 -3
- data/lib/tcell_agent/settings_reporter.rb +0 -93
- data/lib/tcell_agent/sinatra.rb +1 -0
- data/lib/tcell_agent/tcell_context.rb +16 -7
- data/lib/tcell_agent/utils/headers.rb +0 -1
- data/lib/tcell_agent/utils/strings.rb +2 -2
- data/lib/tcell_agent/version.rb +1 -1
- data/lib/tcell_agent.rb +8 -16
- data/spec/cruby_spec_helper.rb +26 -0
- data/spec/lib/tcell_agent/configuration_spec.rb +62 -212
- data/spec/lib/tcell_agent/instrument_servers_spec.rb +95 -0
- data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
- data/spec/lib/tcell_agent/{cmdi_spec.rb → instrumentation/cmdi_spec.rb} +50 -0
- data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +211 -272
- data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +213 -223
- data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +95 -61
- data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +120 -2
- data/spec/lib/tcell_agent/patches_spec.rb +2 -1
- data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +1 -2
- data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +5 -6
- data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +21 -2
- data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +1 -1
- data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +13 -8
- data/spec/lib/tcell_agent/rails/better_ip_spec.rb +9 -11
- data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +6 -6
- data/spec/lib/tcell_agent/rails/dlp_spec.rb +1 -0
- data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +10 -2
- data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -1
- data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +4 -4
- data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -89
- data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
- data/spec/spec_helper.rb +9 -1
- data/spec/support/builders.rb +8 -7
- data/spec/support/server_mocks/passenger_mock.rb +7 -0
- data/spec/support/server_mocks/puma_mock.rb +21 -0
- data/spec/support/server_mocks/rails_mock.rb +7 -0
- data/spec/support/server_mocks/thin_mock.rb +7 -0
- data/spec/support/server_mocks/unicorn_mock.rb +11 -0
- data/spec/support/shared_spec.rb +29 -0
- data/tcell_agent.gemspec +14 -14
- metadata +46 -29
- data/Rakefile +0 -18
- data/lib/tcell_agent/authlogic.rb +0 -23
- data/lib/tcell_agent/config/unknown_options.rb +0 -119
- data/lib/tcell_agent/devise.rb +0 -33
- data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +0 -25
- data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +0 -123
- data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +0 -159
- data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
- data/lib/tcell_agent/rust/tcellagent-4.14.0.dll +0 -0
- data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
|
@@ -1,56 +1,61 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
require 'tcell_agent/configuration'
|
|
4
|
+
require 'tcell_agent/instrumentation'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
module TCellAgent
|
|
7
|
+
require 'tcell_agent/agent'
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
Authlogic::Session::Base.class_eval do
|
|
10
|
+
alias_method :tcell_save, :save
|
|
11
|
+
def save(&block)
|
|
12
|
+
return tcell_save(&block) unless TCellAgent.configuration.should_intercept_requests?
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
user_logged_in_before = !user.nil?
|
|
15
|
+
success = tcell_save(&block)
|
|
16
|
+
user_logged_in_after = !user.nil?
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
TCellAgent::Instrumentation.safe_block('Authlogic login info') do
|
|
19
|
+
user_id = nil
|
|
20
|
+
password = nil
|
|
21
|
+
user_valid = nil
|
|
22
|
+
TCellAgent::Instrumentation.safe_block('getting userid for login form') do
|
|
23
|
+
user_id = send(self.class.login_field.to_sym)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
request = Authlogic::Session::Base.controller.request
|
|
27
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
28
|
+
|
|
29
|
+
return success unless tcell_data
|
|
30
|
+
|
|
31
|
+
login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
|
|
32
|
+
if user_logged_in_before && user_logged_in_after
|
|
33
|
+
# password changed or logged in as another user
|
|
34
|
+
elsif !user_logged_in_before && !user_logged_in_after
|
|
35
|
+
TCellAgent::Instrumentation.safe_block('checking if user is valid') do
|
|
36
|
+
error_messages = errors.messages[login_field]
|
|
25
37
|
|
|
26
|
-
|
|
27
|
-
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
28
|
-
|
|
29
|
-
return success unless tcell_data
|
|
30
|
-
|
|
31
|
-
login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
|
|
32
|
-
if user_logged_in_before && user_logged_in_after
|
|
33
|
-
# password changed or logged in as another user
|
|
34
|
-
elsif !user_logged_in_before && !user_logged_in_after
|
|
35
|
-
login_policy.report_login_failure(
|
|
36
|
-
user_id,
|
|
37
|
-
password,
|
|
38
|
-
request.env,
|
|
39
|
-
user_valid,
|
|
40
|
-
tcell_data
|
|
41
|
-
)
|
|
42
|
-
elsif !user_logged_in_before && user_logged_in_after
|
|
43
|
-
login_policy.report_login_success(
|
|
44
|
-
user_id,
|
|
45
|
-
request.env,
|
|
46
|
-
tcell_data
|
|
47
|
-
)
|
|
38
|
+
user_valid = error_messages.empty?
|
|
48
39
|
end
|
|
49
|
-
end
|
|
50
40
|
|
|
51
|
-
|
|
41
|
+
login_policy.report_login_failure(
|
|
42
|
+
user_id,
|
|
43
|
+
password,
|
|
44
|
+
request.env,
|
|
45
|
+
user_valid,
|
|
46
|
+
tcell_data
|
|
47
|
+
)
|
|
48
|
+
elsif !user_logged_in_before && user_logged_in_after
|
|
49
|
+
tcell_data.user_id = user_id if user_id && tcell_data.user_id.nil?
|
|
50
|
+
login_policy.report_login_success(
|
|
51
|
+
user_id,
|
|
52
|
+
request.env,
|
|
53
|
+
tcell_data
|
|
54
|
+
)
|
|
55
|
+
end
|
|
52
56
|
end
|
|
57
|
+
|
|
58
|
+
success
|
|
53
59
|
end
|
|
54
60
|
end
|
|
55
|
-
|
|
56
61
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'tcell_agent/rails/auth/userinfo'
|
|
2
|
+
|
|
3
|
+
module TCellAgent
|
|
4
|
+
TCellAgent::UserInformation.class_eval do
|
|
5
|
+
class << self
|
|
6
|
+
alias_method :original_get_user_from_request, :get_user_from_request
|
|
7
|
+
def get_user_from_request(request)
|
|
8
|
+
orig_user_id = original_get_user_from_request(request)
|
|
9
|
+
begin
|
|
10
|
+
if request.session && request.session.key?('user_credentials_id')
|
|
11
|
+
return request.session['user_credentials_id'].to_s
|
|
12
|
+
end
|
|
13
|
+
rescue StandardError
|
|
14
|
+
return orig_user_id
|
|
15
|
+
end
|
|
16
|
+
orig_user_id
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -1,127 +1,128 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
module
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
TCellAgent
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
end
|
|
1
|
+
module TCellAgent
|
|
2
|
+
require 'base64'
|
|
3
|
+
require 'tcell_agent/agent'
|
|
4
|
+
|
|
5
|
+
module DeviseInstrumentation
|
|
6
|
+
module TCellFailureAppRespond
|
|
7
|
+
def respond
|
|
8
|
+
TCellAgent::Instrumentation.safe_block('Devise Failure App Respond') do
|
|
9
|
+
if TCellAgent.configuration.should_intercept_requests?
|
|
10
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
11
|
+
if tcell_data
|
|
12
|
+
# in the case of http auth, user_id is set in
|
|
13
|
+
# Devise::Strategies::Authenticatable.valid_for_http_auth?
|
|
14
|
+
user_id = tcell_data.user_id
|
|
15
|
+
user_id ||= _get_tcell_username
|
|
16
|
+
|
|
17
|
+
# in the case of http auth, password is set in
|
|
18
|
+
# Devise::Strategies::Authenticatable.valid_for_http_auth?
|
|
19
|
+
password = tcell_data.password
|
|
20
|
+
password ||= _get_tcell_password
|
|
21
|
+
|
|
22
|
+
user_valid = warden_message != :not_found_in_database if defined?(warden_message)
|
|
23
|
+
|
|
24
|
+
login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
|
|
25
|
+
login_policy.report_login_failure(
|
|
26
|
+
user_id,
|
|
27
|
+
password,
|
|
28
|
+
request.env,
|
|
29
|
+
user_valid,
|
|
30
|
+
tcell_data
|
|
31
|
+
)
|
|
33
32
|
end
|
|
34
33
|
end
|
|
35
|
-
|
|
36
|
-
super if defined?(super)
|
|
37
34
|
end
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
36
|
+
super if defined?(super)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def _get_tcell_username
|
|
40
|
+
tcell_username = nil
|
|
41
|
+
TCellAgent::Instrumentation.safe_block('Devise Get TCell Username') do
|
|
42
|
+
keys = scope_class.authentication_keys.dup
|
|
43
|
+
user_params = request.POST.fetch('user', {})
|
|
44
|
+
keys.each do |key|
|
|
45
|
+
next_usename = user_params.fetch(key, nil)
|
|
46
|
+
if next_usename
|
|
47
|
+
tcell_username ||= ''
|
|
48
|
+
tcell_username += next_usename
|
|
50
49
|
end
|
|
51
50
|
end
|
|
52
|
-
tcell_username
|
|
53
51
|
end
|
|
52
|
+
tcell_username
|
|
53
|
+
end
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
end
|
|
61
|
-
tcell_password
|
|
55
|
+
def _get_tcell_password
|
|
56
|
+
tcell_password = nil
|
|
57
|
+
TCellAgent::Instrumentation.safe_block('Devise Get TCell Password') do
|
|
58
|
+
user_params = request.POST.fetch('user', {})
|
|
59
|
+
tcell_password = user_params['password']
|
|
62
60
|
end
|
|
61
|
+
tcell_password
|
|
63
62
|
end
|
|
64
63
|
end
|
|
64
|
+
end
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
# prepend is ruby 2+ feature
|
|
67
|
+
Devise::FailureApp.send(:prepend, DeviseInstrumentation::TCellFailureAppRespond)
|
|
68
|
+
|
|
69
|
+
Devise::Strategies::Authenticatable.class_eval do
|
|
70
|
+
alias_method :tcell_valid_for_http_auth?, :valid_for_http_auth?
|
|
71
|
+
def valid_for_http_auth?
|
|
72
|
+
is_valid = tcell_valid_for_http_auth?
|
|
73
|
+
|
|
74
|
+
TCellAgent::Instrumentation.safe_block('Devise set username for http basic auth') do
|
|
75
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
76
|
+
if http_auth_hash && tcell_data
|
|
77
|
+
username = http_auth_hash[http_authentication_key]
|
|
78
|
+
password = http_auth_hash[:password]
|
|
79
|
+
tcell_data.user_id = username if username && !tcell_data.user_id
|
|
80
|
+
tcell_data.password = password if password && !tcell_data.password
|
|
81
|
+
end
|
|
82
|
+
end
|
|
68
83
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def valid_for_http_auth?
|
|
72
|
-
is_valid = tcell_valid_for_http_auth?
|
|
84
|
+
is_valid
|
|
85
|
+
end
|
|
73
86
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
password = http_auth_hash[:password]
|
|
79
|
-
tcell_data.user_id = username if username && !tcell_data.user_id
|
|
80
|
-
tcell_data.password = password if password && !tcell_data.password
|
|
81
|
-
end
|
|
82
|
-
end
|
|
87
|
+
alias_method :tcell_validate, :validate
|
|
88
|
+
def validate(resource, &block)
|
|
89
|
+
is_valid = tcell_validate(resource, &block)
|
|
90
|
+
send_event = is_valid
|
|
83
91
|
|
|
84
|
-
|
|
92
|
+
# gets the first entry in the current backtrace
|
|
93
|
+
# syntax suggested by rubocop to improve performance
|
|
94
|
+
if caller(1..1).first.include? 'two_factor_authenticatable'
|
|
95
|
+
TCellAgent.logger.debug('Not sending login success event for Devise::Strategies::TwoFactorAuthenticatable since 2fa is unsupported', 'TCellAgent::DeviseInstrumentation')
|
|
96
|
+
send_event = false
|
|
85
97
|
end
|
|
86
98
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
# gets the first entry in the current backtrace
|
|
93
|
-
# syntax suggested by rubocop to improve performance
|
|
94
|
-
if caller(1..1).first.include? 'two_factor_authenticatable'
|
|
95
|
-
TCellAgent.logger.debug('Not sending login success event for Devise::Strategies::TwoFactorAuthenticatable since 2fa is unsupported', 'TCellAgent::DeviseInstrumentation')
|
|
96
|
-
send_event = false
|
|
97
|
-
end
|
|
99
|
+
TCellAgent::Instrumentation.safe_block('Devise Authenticatable Validate') do
|
|
100
|
+
if send_event && TCellAgent.configuration.should_intercept_requests?
|
|
101
|
+
username = nil
|
|
102
|
+
(authentication_keys || []).each do |auth_key|
|
|
103
|
+
attr = authentication_hash[auth_key] unless authentication_hash.nil?
|
|
98
104
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
username = nil
|
|
103
|
-
(authentication_keys || []).each do |auth_key|
|
|
104
|
-
attr = authentication_hash[auth_key]
|
|
105
|
-
if attr
|
|
106
|
-
username ||= ''
|
|
107
|
-
username += attr
|
|
108
|
-
end
|
|
105
|
+
if attr
|
|
106
|
+
username ||= ''
|
|
107
|
+
username += attr
|
|
109
108
|
end
|
|
110
|
-
|
|
111
|
-
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
112
|
-
return is_valid unless tcell_data
|
|
113
|
-
|
|
114
|
-
login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
|
|
115
|
-
login_policy.report_login_success(
|
|
116
|
-
username,
|
|
117
|
-
request.env,
|
|
118
|
-
tcell_data
|
|
119
|
-
)
|
|
120
109
|
end
|
|
121
|
-
end
|
|
122
110
|
|
|
123
|
-
|
|
111
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
112
|
+
return is_valid unless tcell_data
|
|
113
|
+
|
|
114
|
+
tcell_data.user_id = username if username && tcell_data.user_id.nil?
|
|
115
|
+
|
|
116
|
+
login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
|
|
117
|
+
login_policy.report_login_success(
|
|
118
|
+
username,
|
|
119
|
+
request.env,
|
|
120
|
+
tcell_data
|
|
121
|
+
)
|
|
122
|
+
end
|
|
124
123
|
end
|
|
124
|
+
|
|
125
|
+
is_valid
|
|
125
126
|
end
|
|
126
127
|
end
|
|
127
128
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'devise'
|
|
2
|
+
require 'devise/rails'
|
|
3
|
+
require 'devise/strategies/database_authenticatable'
|
|
4
|
+
require 'tcell_agent/rails/auth/userinfo'
|
|
5
|
+
|
|
6
|
+
module TCellAgent
|
|
7
|
+
TCellAgent::UserInformation.class_eval do
|
|
8
|
+
class << self
|
|
9
|
+
alias_method :original_get_user_from_request, :get_user_from_request
|
|
10
|
+
def get_user_from_request(request)
|
|
11
|
+
orig_user_id = original_get_user_from_request(request)
|
|
12
|
+
begin
|
|
13
|
+
if request.session && request.session.key?('warden.user.user.key')
|
|
14
|
+
userkey = request.session['warden.user.user.key']
|
|
15
|
+
user_id = if userkey.length == 2
|
|
16
|
+
userkey[0][0]
|
|
17
|
+
else
|
|
18
|
+
userkey[1][0]
|
|
19
|
+
end
|
|
20
|
+
return user_id.to_s if user_id.is_a? Integer
|
|
21
|
+
end
|
|
22
|
+
rescue StandardError
|
|
23
|
+
return orig_user_id
|
|
24
|
+
end
|
|
25
|
+
orig_user_id
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -1,65 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
require 'tcell_agent/agent'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
module TCellAgent
|
|
4
|
+
module DoorkeeperInstrumentation
|
|
5
|
+
Doorkeeper::TokensController.class_eval do
|
|
6
|
+
alias_method :tcell_authorize_response, :authorize_response
|
|
7
|
+
def authorize_response
|
|
8
|
+
result = tcell_authorize_response
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Doorkeeper::TokensController.class_eval do
|
|
9
|
-
alias_method :tcell_authorize_response, :authorize_response
|
|
10
|
-
def authorize_response
|
|
11
|
-
result = tcell_authorize_response
|
|
10
|
+
TCellAgent::Instrumentation.safe_block('Doorkeeper Token Authorize') do
|
|
11
|
+
return result unless TCellAgent.configuration.should_intercept_requests?
|
|
12
12
|
|
|
13
|
-
TCellAgent
|
|
14
|
-
|
|
13
|
+
login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
|
|
14
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
16
|
+
return unless tcell_data
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
headers = request.env
|
|
18
|
+
headers = request.env
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
password = nil
|
|
32
|
-
user_valid = nil
|
|
33
|
-
login_policy.report_login_failure(
|
|
34
|
-
user_id,
|
|
35
|
-
password,
|
|
36
|
-
headers,
|
|
37
|
-
user_valid,
|
|
38
|
-
tcell_data
|
|
39
|
-
)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
result
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
module TCellAuthorizationsNew
|
|
48
|
-
def new
|
|
49
|
-
super if defined?(super)
|
|
50
|
-
|
|
51
|
-
TCellAgent::Instrumentation.safe_block('Doorkeeper Token Authorize') do
|
|
52
|
-
return unless TCellAgent.configuration.should_intercept_requests?
|
|
53
|
-
return unless pre_auth.error
|
|
54
|
-
|
|
55
|
-
login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
|
|
56
|
-
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
57
|
-
|
|
58
|
-
return unless tcell_data
|
|
59
|
-
|
|
60
|
-
user_id = current_resource_owner.id
|
|
20
|
+
if result.is_a?(Doorkeeper::OAuth::TokenResponse)
|
|
21
|
+
user_id = result.token.resource_owner_id
|
|
22
|
+
login_policy.report_login_success(
|
|
23
|
+
user_id,
|
|
24
|
+
headers,
|
|
25
|
+
tcell_data
|
|
26
|
+
)
|
|
27
|
+
elsif result.is_a?(Doorkeeper::OAuth::ErrorResponse)
|
|
28
|
+
user_id = request.POST['client_id']
|
|
61
29
|
password = nil
|
|
62
|
-
headers = request.env
|
|
63
30
|
user_valid = nil
|
|
64
31
|
login_policy.report_login_failure(
|
|
65
32
|
user_id,
|
|
@@ -70,10 +37,40 @@ if TCellAgent.configuration.should_instrument_doorkeeper? && defined?(Doorkeeper
|
|
|
70
37
|
)
|
|
71
38
|
end
|
|
72
39
|
end
|
|
40
|
+
|
|
41
|
+
result
|
|
73
42
|
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
module TCellAuthorizationsNew
|
|
46
|
+
def new
|
|
47
|
+
super if defined?(super)
|
|
48
|
+
|
|
49
|
+
TCellAgent::Instrumentation.safe_block('Doorkeeper Token Authorize') do
|
|
50
|
+
return unless TCellAgent.configuration.should_intercept_requests?
|
|
51
|
+
return unless pre_auth.error
|
|
74
52
|
|
|
75
|
-
|
|
76
|
-
|
|
53
|
+
login_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LOGINFRAUD)
|
|
54
|
+
tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
55
|
+
|
|
56
|
+
return unless tcell_data
|
|
57
|
+
|
|
58
|
+
user_id = current_resource_owner.id
|
|
59
|
+
password = nil
|
|
60
|
+
headers = request.env
|
|
61
|
+
user_valid = nil
|
|
62
|
+
login_policy.report_login_failure(
|
|
63
|
+
user_id,
|
|
64
|
+
password,
|
|
65
|
+
headers,
|
|
66
|
+
user_valid,
|
|
67
|
+
tcell_data
|
|
68
|
+
)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
77
71
|
end
|
|
72
|
+
|
|
73
|
+
# prepend is ruby 2+ feature
|
|
74
|
+
Doorkeeper::AuthorizationsController.send(:prepend, TCellAuthorizationsNew)
|
|
78
75
|
end
|
|
79
76
|
end
|
|
File without changes
|
|
@@ -4,28 +4,16 @@ require 'tcell_agent/instrumentation'
|
|
|
4
4
|
module TCellAgent
|
|
5
5
|
module Utils
|
|
6
6
|
module Rails
|
|
7
|
-
def self.
|
|
8
|
-
|
|
9
|
-
TCellAgent::Instrumentation.safe_block('Extracting reverse proxy IP') do
|
|
10
|
-
reverse_proxy_header = TCellAgent.configuration.reverse_proxy_ip_address_header
|
|
11
|
-
reverse_proxy_header = if TCellAgent::Utils::Strings.present?(reverse_proxy_header)
|
|
12
|
-
'HTTP_' + reverse_proxy_header.upcase.tr('-', '_')
|
|
13
|
-
else
|
|
14
|
-
'HTTP_X_FORWARDED_FOR'
|
|
15
|
-
end
|
|
7
|
+
def self.reverse_proxy_header(request)
|
|
8
|
+
return unless TCellAgent.configuration.reverse_proxy
|
|
16
9
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
x_forwarded_for.split(',')[0].strip
|
|
20
|
-
else
|
|
21
|
-
request.ip
|
|
22
|
-
end
|
|
10
|
+
TCellAgent::Instrumentation.safe_block('Extracting reverse proxy header') do
|
|
11
|
+
reverse_proxy_header = TCellAgent.configuration.reverse_proxy_ip_address_header
|
|
23
12
|
|
|
24
|
-
|
|
25
|
-
end
|
|
26
|
-
end
|
|
13
|
+
return if reverse_proxy_header.nil? || reverse_proxy_header.empty?
|
|
27
14
|
|
|
28
|
-
|
|
15
|
+
return request.env["HTTP_#{reverse_proxy_header.upcase.tr('-', '_')}"]
|
|
16
|
+
end
|
|
29
17
|
end
|
|
30
18
|
end
|
|
31
19
|
end
|
|
@@ -16,12 +16,4 @@ module TCellAgent
|
|
|
16
16
|
super if defined?(super)
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
|
-
|
|
20
|
-
class MyRailtie < Rails::Railtie
|
|
21
|
-
initializer 'tcell.sensors' do |_app|
|
|
22
|
-
ActiveSupport.on_load :action_controller do
|
|
23
|
-
ActionController::Base.send(:include, TCellAgent::CsrfExceptionReporter)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
19
|
end
|
|
@@ -37,6 +37,7 @@ module TCellAgent
|
|
|
37
37
|
dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
|
|
38
38
|
tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
39
39
|
return unless tcell_context && dataex_policy && dataex_policy.actions_for_form_parameter?
|
|
40
|
+
|
|
40
41
|
for_params(request) do |_method, param_name, param_value|
|
|
41
42
|
actions = dataex_policy.get_actions_for_form_parameter(param_name, tcell_context.route_id)
|
|
42
43
|
if actions
|
|
@@ -51,11 +52,13 @@ module TCellAgent
|
|
|
51
52
|
dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
|
|
52
53
|
tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
53
54
|
return unless tcell_context && dataex_policy && dataex_policy.actions_for_headers?
|
|
55
|
+
|
|
54
56
|
headers = request.env.select { |k, _v| k.start_with? 'HTTP_' }
|
|
55
57
|
headers.each do |header_name, header_value|
|
|
56
58
|
header_name = header_name.sub(/^HTTP_/, '').tr('_', '-')
|
|
57
59
|
actions = dataex_policy.get_actions_for_header(header_name)
|
|
58
60
|
next unless actions
|
|
61
|
+
|
|
59
62
|
actions.each do |action|
|
|
60
63
|
tcell_context.add_filter_for_header_value(header_value, action, header_name)
|
|
61
64
|
end
|
|
@@ -66,9 +69,11 @@ module TCellAgent
|
|
|
66
69
|
dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
|
|
67
70
|
tcell_context = request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
68
71
|
return unless tcell_context && dataex_policy && dataex_policy.actions_for_cookie?
|
|
72
|
+
|
|
69
73
|
request.cookies.each do |cookie_name, cookie_value|
|
|
70
74
|
actions = dataex_policy.get_actions_for_cookie(cookie_name)
|
|
71
75
|
next unless actions
|
|
76
|
+
|
|
72
77
|
actions.each do |action|
|
|
73
78
|
tcell_context.add_filter_for_cookie_value(cookie_value, action, cookie_name)
|
|
74
79
|
end
|