tcell_agent 2.7.0 → 2.7.1
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/lib/tcell_agent/agent.rb +1 -2
- data/lib/tcell_agent/instrumentation.rb +0 -192
- data/lib/tcell_agent/policies/policies_manager.rb +1 -17
- data/lib/tcell_agent/policies/policy_polling.rb +1 -2
- data/lib/tcell_agent/policies/policy_types.rb +0 -1
- data/lib/tcell_agent/rails/database.rb +49 -0
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -1
- data/lib/tcell_agent/rails/railties/tcell_agent_database_railties.rb +81 -0
- data/lib/tcell_agent/rails/railties/tcell_agent_railties.rb +0 -1
- data/lib/tcell_agent/rails/routes.rb +0 -8
- data/lib/tcell_agent/rust/libtcellagent-alpine.so +0 -0
- data/lib/tcell_agent/rust/libtcellagent-x64.dll +0 -0
- data/lib/tcell_agent/rust/libtcellagent.dylib +0 -0
- data/lib/tcell_agent/rust/libtcellagent.so +0 -0
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +0 -17
- data/lib/tcell_agent/version.rb +1 -1
- data/lib/tcell_agent.rb +5 -3
- data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +5 -16
- data/spec/lib/tcell_agent/rails/database.rb +60 -0
- data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -2
- data/spec/support/force_logger_mocking.rb +0 -8
- metadata +6 -16
- data/lib/tcell_agent/policies/dataloss_policy.rb +0 -304
- data/lib/tcell_agent/rails/dlp/process_request.rb +0 -83
- data/lib/tcell_agent/rails/dlp.rb +0 -410
- data/lib/tcell_agent/rails/dlp_handler.rb +0 -63
- data/lib/tcell_agent/sensor_events/dlp.rb +0 -53
- data/lib/tcell_agent/sinatra.rb +0 -38
- data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +0 -222
- data/spec/lib/tcell_agent/rails/dlp_spec.rb +0 -1040
- data/spec/lib/tcell_agent/rails/logger_spec.rb +0 -169
- data/spec/lib/tcell_agent/sensor_events/dlp_spec.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60417237022f31c4843ffb12a013c385b35ffc40adc299947e53bb3fb44dcce7
|
4
|
+
data.tar.gz: b6231f1628e83d4f4ead9c277786dc0b8c57160f518e701f58ab357b9fa4b223
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '08f8ed5ffa676d80512a5ef821aae44bb59037a59c0cf4639acac0ce690805f26c4249f4639780088230d9cd050c3148af0b8de6c797f431f1cec9f4f8e39440'
|
7
|
+
data.tar.gz: 60fe10b0f131c50f2e69e4d27199ba53a8ab5f708e578f51793ef09346b6a965c32b807f3f6aa57eb0b704495e254a6cf16f1df6f9318e1f9db0f4ffa8e0b96f
|
data/lib/tcell_agent/agent.rb
CHANGED
@@ -89,8 +89,7 @@ module TCellAgent
|
|
89
89
|
policies_and_enablements = result['new_policies_and_enablements'] || {}
|
90
90
|
|
91
91
|
@policies_manager.process_policy_json(
|
92
|
-
policies_and_enablements['enablements']
|
93
|
-
policies_and_enablements['policies']
|
92
|
+
policies_and_enablements['enablements']
|
94
93
|
)
|
95
94
|
|
96
95
|
@policy_polling = PolicyPolling.new(@policies_manager, @native_agent)
|
@@ -1,65 +1,11 @@
|
|
1
1
|
# See the file "LICENSE" for the full license governing this code.
|
2
2
|
require 'tcell_agent/configuration'
|
3
3
|
require 'tcell_agent/version'
|
4
|
-
require 'date'
|
5
|
-
require 'cgi'
|
6
4
|
|
7
5
|
module TCellAgent
|
8
6
|
module Instrumentation
|
9
7
|
TCELL_ID = 'tcell.request_data'.freeze
|
10
8
|
|
11
|
-
class ContextFilter
|
12
|
-
attr_accessor :type
|
13
|
-
attr_accessor :rule
|
14
|
-
attr_accessor :context
|
15
|
-
attr_accessor :parameter
|
16
|
-
attr_accessor :database
|
17
|
-
attr_accessor :schema
|
18
|
-
attr_accessor :table
|
19
|
-
attr_accessor :field
|
20
|
-
|
21
|
-
DATABASE = 'db'.freeze
|
22
|
-
REQUEST = 'request'.freeze
|
23
|
-
|
24
|
-
def for_request(context, parameter, rule)
|
25
|
-
self.type = ContextFilter::REQUEST
|
26
|
-
self.context = context
|
27
|
-
self.parameter = parameter
|
28
|
-
self.rule = rule
|
29
|
-
self
|
30
|
-
end
|
31
|
-
|
32
|
-
def create_hash_value
|
33
|
-
"#{type}#{context}#{parameter}#{database}#{schema}#{table}#{field}#{rule}".hash
|
34
|
-
end
|
35
|
-
|
36
|
-
def eql?(other)
|
37
|
-
hash == other.hash
|
38
|
-
end
|
39
|
-
|
40
|
-
def hash
|
41
|
-
create_hash_value
|
42
|
-
end
|
43
|
-
|
44
|
-
def for_database(database, schema, table, field, rule)
|
45
|
-
self.type = ContextFilter::DATABASE
|
46
|
-
self.database = database
|
47
|
-
self.schema = schema
|
48
|
-
self.table = table
|
49
|
-
self.field = field
|
50
|
-
self.rule = rule
|
51
|
-
self
|
52
|
-
end
|
53
|
-
|
54
|
-
def for_request(context, parameter, rule) # rubocop:disable Lint/DuplicateMethods
|
55
|
-
self.type = ContextFilter::REQUEST
|
56
|
-
self.context = context
|
57
|
-
self.parameter = parameter
|
58
|
-
self.rule = rule
|
59
|
-
self
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
9
|
class TCellData
|
64
10
|
attr_accessor :transaction_id, :session_id, :hmac_session_id, :user_id,
|
65
11
|
:password, :route_id, :path, :uri, :fullpath, :context_filters_by_term,
|
@@ -68,150 +14,12 @@ module TCellAgent
|
|
68
14
|
:referrer, :csrf_exception_name, :sql_exceptions, :database_result_sizes,
|
69
15
|
:reverse_proxy_header_value
|
70
16
|
|
71
|
-
def self.filterx(sanitize_string, event_flag, replace_flag, term)
|
72
|
-
send_event = false
|
73
|
-
sanitize_string.gsub!(term) do |m|
|
74
|
-
if replace_flag
|
75
|
-
m = '[redacted]'
|
76
|
-
send_event = true
|
77
|
-
elsif event_flag
|
78
|
-
# m = "[hash]"
|
79
|
-
send_event = true
|
80
|
-
end
|
81
|
-
m
|
82
|
-
end
|
83
|
-
send_event
|
84
|
-
end
|
85
|
-
|
86
17
|
def initialize
|
87
18
|
@patches_blocking_triggered = false
|
88
|
-
@context_filters_by_term = Hash.new { |h, k| h[k] = Set.new }
|
89
19
|
@sql_exceptions = []
|
90
20
|
@database_result_sizes = []
|
91
21
|
end
|
92
22
|
|
93
|
-
def valid_term?(term)
|
94
|
-
return true if !term.nil? && term != '' && term.to_s.length >= 5
|
95
|
-
|
96
|
-
false
|
97
|
-
end
|
98
|
-
|
99
|
-
def add_response_db_filter(term, action_obj, database, schema, table, field)
|
100
|
-
return unless valid_term?(term)
|
101
|
-
|
102
|
-
context_filters_by_term[term.to_s].add(ContextFilter.new.for_database(database, schema, table, field, action_obj))
|
103
|
-
end
|
104
|
-
|
105
|
-
def add_filter_for_request_parameter(term, rule, parameter_name)
|
106
|
-
return unless valid_term?(term)
|
107
|
-
|
108
|
-
context_filters_by_term[term.to_s].add(ContextFilter.new.for_request('form', parameter_name, rule))
|
109
|
-
end
|
110
|
-
|
111
|
-
def add_filter_for_header_value(term, rule, header_name)
|
112
|
-
return unless valid_term?(term)
|
113
|
-
|
114
|
-
context_filters_by_term[term.to_s].add(ContextFilter.new.for_request('header', header_name, rule))
|
115
|
-
end
|
116
|
-
|
117
|
-
def add_filter_for_cookie_value(term, rule, cookie_name)
|
118
|
-
return unless valid_term?(term)
|
119
|
-
|
120
|
-
context_filters_by_term[term.to_s].add(ContextFilter.new.for_request('cookie', cookie_name, rule))
|
121
|
-
end
|
122
|
-
|
123
|
-
def filter_body!(body)
|
124
|
-
dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
|
125
|
-
if dlp_policy && session_id
|
126
|
-
session_id_actions = dlp_policy.get_actions_for_session_id
|
127
|
-
if session_id_actions
|
128
|
-
send_flag = TCellData.filterx(body, session_id_actions.body_event, session_id_actions.body_redact, session_id)
|
129
|
-
if send_flag
|
130
|
-
TCellAgent.send_event(
|
131
|
-
TCellAgent::SensorEvents::DlpEvent.new(
|
132
|
-
route_id,
|
133
|
-
uri,
|
134
|
-
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_BODY,
|
135
|
-
session_id_actions.action_id
|
136
|
-
).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
|
137
|
-
)
|
138
|
-
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
context_filters_by_term.sort_by { |term, _context_filters| -term.length }.each do |term, context_filters|
|
143
|
-
replace_filters = (context_filters.select { |context_filter| context_filter.rule.body_redact == true })
|
144
|
-
event_filters = (context_filters.select { |context_filter| (context_filter.rule.body_redact != true && context_filter.rule.body_event == true) })
|
145
|
-
send_flag = TCellData.filterx(body, !event_filters.empty?, !replace_filters.empty?, term)
|
146
|
-
send_flag ||= TCellData.filterx(body, !event_filters.empty?, !replace_filters.empty?, CGI.escapeHTML(term))
|
147
|
-
next unless send_flag
|
148
|
-
|
149
|
-
(replace_filters + event_filters).each do |filter|
|
150
|
-
base_event = TCellAgent::SensorEvents::DlpEvent.new(
|
151
|
-
route_id,
|
152
|
-
uri,
|
153
|
-
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_BODY,
|
154
|
-
filter.rule.action_id
|
155
|
-
)
|
156
|
-
if filter.type == ContextFilter::DATABASE
|
157
|
-
TCellAgent.send_event(
|
158
|
-
base_event.for_database(filter.database, filter.schema, filter.table, filter.field)
|
159
|
-
)
|
160
|
-
elsif filter.type == ContextFilter::REQUEST
|
161
|
-
TCellAgent.send_event(
|
162
|
-
base_event.for_request(filter.context, filter.parameter)
|
163
|
-
)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
body
|
168
|
-
end
|
169
|
-
|
170
|
-
def filter_log(log_msg)
|
171
|
-
dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DATALOSS)
|
172
|
-
if dlp_policy && session_id
|
173
|
-
session_id_actions = dlp_policy.get_actions_for_session_id
|
174
|
-
if session_id_actions
|
175
|
-
send_flag = TCellData.filterx(log_msg, session_id_actions.log_event, session_id_actions.log_redact, session_id)
|
176
|
-
if send_flag
|
177
|
-
TCellAgent.send_event(
|
178
|
-
TCellAgent::SensorEvents::DlpEvent.new(
|
179
|
-
route_id,
|
180
|
-
uri,
|
181
|
-
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_LOG,
|
182
|
-
session_id_actions.action_id
|
183
|
-
).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
|
184
|
-
)
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
context_filters_by_term.sort_by { |term, _context_filters| -term.length }.each do |term, context_filters|
|
189
|
-
replace_filters = (context_filters.select { |context_filter| context_filter.rule.log_redact == true })
|
190
|
-
event_filters = (context_filters.select { |context_filter| (context_filter.rule.log_redact != true && context_filter.rule.log_event == true) })
|
191
|
-
send_flag = TCellData.filterx(log_msg, !event_filters.empty?, !replace_filters.empty?, term)
|
192
|
-
next unless send_flag
|
193
|
-
|
194
|
-
(replace_filters + event_filters).each do |filter|
|
195
|
-
base_event = TCellAgent::SensorEvents::DlpEvent.new(
|
196
|
-
route_id,
|
197
|
-
uri,
|
198
|
-
TCellAgent::SensorEvents::DlpEvent::FOUND_IN_LOG,
|
199
|
-
filter.rule.action_id
|
200
|
-
)
|
201
|
-
if filter.type == ContextFilter::DATABASE
|
202
|
-
TCellAgent.send_event(
|
203
|
-
base_event.for_database(filter.database, filter.schema, filter.table, filter.field)
|
204
|
-
)
|
205
|
-
elsif filter.type == ContextFilter::REQUEST
|
206
|
-
TCellAgent.send_event(
|
207
|
-
base_event.for_request(filter.context, filter.parameter)
|
208
|
-
)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
log_msg
|
213
|
-
end
|
214
|
-
|
215
23
|
def to_s
|
216
24
|
"<#{self.class.name} transaction_id: #{transaction_id} session_id: #{session_id} " \
|
217
25
|
"hmac_session_id: #{hmac_session_id} user_id: #{user_id} route_id: #{route_id} " \
|
@@ -4,7 +4,6 @@ require 'tcell_agent/policies/policy_types'
|
|
4
4
|
|
5
5
|
require 'tcell_agent/policies/appfirewall_policy'
|
6
6
|
require 'tcell_agent/policies/command_injection_policy'
|
7
|
-
require 'tcell_agent/policies/dataloss_policy'
|
8
7
|
require 'tcell_agent/policies/headers_policy'
|
9
8
|
require 'tcell_agent/policies/http_redirect_policy'
|
10
9
|
require 'tcell_agent/policies/js_agent_policy'
|
@@ -39,22 +38,9 @@ module TCellAgent
|
|
39
38
|
@native_agent, enablements
|
40
39
|
)
|
41
40
|
end
|
42
|
-
|
43
|
-
set_dataloss_policy({ 'dlp' => {} })
|
44
41
|
end
|
45
42
|
|
46
|
-
def
|
47
|
-
TCellAgent::Instrumentation.safe_block('Setting DLP policy') do
|
48
|
-
dlp_api_identifier = TCellAgent::Policies::DataLossPolicy.api_identifier
|
49
|
-
return unless policies_json.key?(dlp_api_identifier)
|
50
|
-
|
51
|
-
@policies[dlp_api_identifier] = TCellAgent::Policies::DataLossPolicy.new(
|
52
|
-
policies_json[dlp_api_identifier]
|
53
|
-
)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def process_policy_json(enablements, policies_json)
|
43
|
+
def process_policy_json(enablements)
|
58
44
|
return if enablements.nil? || enablements == {}
|
59
45
|
|
60
46
|
RUST_POLICY_CLASSES.each do |policy_class|
|
@@ -62,8 +48,6 @@ module TCellAgent
|
|
62
48
|
@native_agent, enablements
|
63
49
|
)
|
64
50
|
end
|
65
|
-
|
66
|
-
set_dataloss_policy(policies_json)
|
67
51
|
end
|
68
52
|
end
|
69
53
|
end
|
@@ -42,8 +42,7 @@ module TCellAgent
|
|
42
42
|
result = native_agent.poll_new_policies
|
43
43
|
policies_and_enablements = result['new_policies_and_enablements'] || {}
|
44
44
|
@policies_manager.process_policy_json(
|
45
|
-
policies_and_enablements['enablements']
|
46
|
-
policies_and_enablements['policies']
|
45
|
+
policies_and_enablements['enablements']
|
47
46
|
)
|
48
47
|
rescue StandardError => e
|
49
48
|
module_logger.error("Error in polling policies: #{e.message}")
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# See the file "LICENSE" for the full license governing this code.
|
2
|
+
|
3
|
+
require 'rails'
|
4
|
+
require 'tcell_agent/agent'
|
5
|
+
require 'tcell_agent/rails/middleware/context_middleware'
|
6
|
+
require 'tcell_agent/instrumentation'
|
7
|
+
|
8
|
+
require 'thread'
|
9
|
+
|
10
|
+
module TCellAgent
|
11
|
+
module Instrumentation
|
12
|
+
module Rails
|
13
|
+
module Database
|
14
|
+
def self.push_exception(message, result)
|
15
|
+
appfirewall_policy = TCellAgent.policy(TCellAgent::PolicyTypes::APPSENSOR)
|
16
|
+
|
17
|
+
return unless appfirewall_policy.enabled
|
18
|
+
|
19
|
+
request_env = TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware::THREADS.fetch(
|
20
|
+
Thread.current.object_id, {}
|
21
|
+
)
|
22
|
+
|
23
|
+
tcell_data = request_env[TCellAgent::Instrumentation::TCELL_ID]
|
24
|
+
|
25
|
+
return unless tcell_data && result.is_a?(ActiveRecord::StatementInvalid)
|
26
|
+
|
27
|
+
tcell_data.sql_exceptions.push(
|
28
|
+
{ 'exception_name' => result.class.name, 'exception_payload' => message }
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.inspect_result_size(results)
|
33
|
+
return if results.empty?
|
34
|
+
|
35
|
+
if TCellAgent.configuration.should_instrument? &&
|
36
|
+
TCellAgent.configuration.should_intercept_requests?
|
37
|
+
|
38
|
+
request_env = TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware::THREADS.fetch(Thread.current.object_id, {})
|
39
|
+
tcell_context = request_env[TCellAgent::Instrumentation::TCELL_ID]
|
40
|
+
|
41
|
+
if tcell_context
|
42
|
+
tcell_context.database_result_sizes.push(results.size)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -77,7 +77,7 @@ module TCellAgent
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def _handle_appsensor_js_agent(request, response)
|
80
|
-
TCellAgent::Instrumentation.safe_block('Handling AppSensor
|
80
|
+
TCellAgent::Instrumentation.safe_block('Handling AppSensor and JSAgent') do
|
81
81
|
status_code, response_headers, response_body = response
|
82
82
|
|
83
83
|
js_agent_handler, script_insert =
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'tcell_agent/rails/database'
|
2
|
+
|
3
|
+
class TCellAgentDatabaseRailtie < Rails::Railtie
|
4
|
+
initializer 'activeservice.autoload', :after => :set_autoload_paths do |_app|
|
5
|
+
if defined?(ActiveRecord)
|
6
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
|
7
|
+
alias_method :tcell_translate_exception, :translate_exception
|
8
|
+
|
9
|
+
if RUBY_VERSION.start_with?('3') || RUBY_VERSION.start_with?('2.7')
|
10
|
+
def translate_exception(*args, **kwargs, &block)
|
11
|
+
result = tcell_translate_exception(*args, **kwargs, &block)
|
12
|
+
|
13
|
+
TCellAgent::Instrumentation.safe_block('Set sql_exception_detected in meta') do
|
14
|
+
TCellAgent::Instrumentation::Rails::Database.push_exception(kwargs.fetch(:message, ''), result)
|
15
|
+
end
|
16
|
+
|
17
|
+
result
|
18
|
+
end
|
19
|
+
else
|
20
|
+
def translate_exception(*args, &block)
|
21
|
+
result = tcell_translate_exception(*args, &block)
|
22
|
+
|
23
|
+
TCellAgent::Instrumentation.safe_block('Set sql_exception_detected in meta') do
|
24
|
+
args_copy = Array.new(args)
|
25
|
+
_ = args_copy.shift
|
26
|
+
message = args_copy.shift
|
27
|
+
|
28
|
+
if message.is_a? Hash
|
29
|
+
TCellAgent::Instrumentation::Rails::Database.push_exception(message.fetch(:message, ''), result)
|
30
|
+
else
|
31
|
+
TCellAgent::Instrumentation::Rails::Database.push_exception(message, result)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
ActiveRecord::Calculations.module_eval do
|
41
|
+
alias_method :tcell_pluck, :pluck
|
42
|
+
def pluck(*column_names)
|
43
|
+
results = tcell_pluck(*column_names)
|
44
|
+
|
45
|
+
TCellAgent::Instrumentation.safe_block('Checking for unusual database result size on pluck') do
|
46
|
+
TCellAgent::Instrumentation::Rails::Database.inspect_result_size(results)
|
47
|
+
end
|
48
|
+
|
49
|
+
results
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
ActiveRecord::Querying.module_eval do
|
54
|
+
if RUBY_VERSION.start_with?('3')
|
55
|
+
alias_method :tcell_find_by_sql, :find_by_sql
|
56
|
+
def find_by_sql(*args, **kwargs, &block)
|
57
|
+
results = tcell_find_by_sql(*args, **kwargs, &block)
|
58
|
+
|
59
|
+
TCellAgent::Instrumentation.safe_block('Checking for unusual database result size on find_by_sql') do
|
60
|
+
TCellAgent::Instrumentation::Rails::Database.inspect_result_size(results)
|
61
|
+
end
|
62
|
+
|
63
|
+
results
|
64
|
+
end
|
65
|
+
|
66
|
+
elsif RUBY_VERSION.start_with?('2')
|
67
|
+
alias_method :tcell_find_by_sql, :find_by_sql
|
68
|
+
def find_by_sql(*args, &block)
|
69
|
+
results = tcell_find_by_sql(*args, &block)
|
70
|
+
|
71
|
+
TCellAgent::Instrumentation.safe_block('Checking for unusual database result size on find_by_sql') do
|
72
|
+
TCellAgent::Instrumentation::Rails::Database.inspect_result_size(results)
|
73
|
+
end
|
74
|
+
|
75
|
+
results
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
require 'tcell_agent/patches'
|
2
2
|
require 'tcell_agent/rails/routes/grape'
|
3
3
|
require 'tcell_agent/rails/routes/route_id'
|
4
|
-
require 'tcell_agent/rails/dlp/process_request'
|
5
|
-
|
6
4
|
require 'json'
|
7
5
|
|
8
6
|
module TCellAgent
|
@@ -146,8 +144,6 @@ module TCellAgent
|
|
146
144
|
if TCellAgent::Instrumentation::Patches.block?(request)
|
147
145
|
return head(403)
|
148
146
|
end
|
149
|
-
|
150
|
-
TCellAgent::DLP.handle_request_dlp_parameters(request)
|
151
147
|
end
|
152
148
|
|
153
149
|
yield
|
@@ -201,8 +197,6 @@ module TCellAgent
|
|
201
197
|
if TCellAgent::Instrumentation::Patches.block?(req)
|
202
198
|
return [403, {}, []]
|
203
199
|
end
|
204
|
-
|
205
|
-
TCellAgent::DLP.handle_request_dlp_parameters(req)
|
206
200
|
end
|
207
201
|
|
208
202
|
tcell_serve(req)
|
@@ -230,8 +224,6 @@ module TCellAgent
|
|
230
224
|
if TCellAgent::Instrumentation::Patches.block?(tcell_request)
|
231
225
|
return [403, {}, []]
|
232
226
|
end
|
233
|
-
|
234
|
-
TCellAgent::DLP.handle_request_dlp_parameters(tcell_request)
|
235
227
|
end
|
236
228
|
|
237
229
|
tcell_call(env)
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -15,23 +15,6 @@ module TCellAgent
|
|
15
15
|
h[0...h.length / 2]
|
16
16
|
end
|
17
17
|
|
18
|
-
def self.strip_values_query_string(query)
|
19
|
-
params = CGI.parse(query)
|
20
|
-
params.each do |param_name, param_values|
|
21
|
-
next if param_values.nil? || param_values.empty?
|
22
|
-
|
23
|
-
params[param_name] = ['']
|
24
|
-
end
|
25
|
-
params.map { |k, v| "#{k}=#{v.join(',')}" }.join('&')
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.strip_uri_values(uri_string)
|
29
|
-
uri = URI(uri_string)
|
30
|
-
query = uri.query
|
31
|
-
uri.query = strip_values_query_string(query) if query
|
32
|
-
uri.to_s
|
33
|
-
end
|
34
|
-
|
35
18
|
def self.get_hmac_key
|
36
19
|
return TCellAgent.configuration.hmac_key if TCellAgent.configuration.hmac_key
|
37
20
|
return TCellAgent.configuration.app_id if TCellAgent.configuration.app_id
|
data/lib/tcell_agent/version.rb
CHANGED
data/lib/tcell_agent.rb
CHANGED
@@ -12,7 +12,9 @@ unless TCellAgent.configuration.disable_all
|
|
12
12
|
|
13
13
|
require 'tcell_agent/instrument_servers'
|
14
14
|
require 'tcell_agent/hooks/login_fraud'
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
|
16
|
+
if defined?(Rails)
|
17
|
+
require 'tcell_agent/rails/railties/tcell_agent_railties' if defined?(Rails)
|
18
|
+
require 'tcell_agent/rails/railties/tcell_agent_database_railties'
|
19
|
+
end
|
18
20
|
end
|
@@ -4,7 +4,7 @@ module TCellAgent
|
|
4
4
|
describe PoliciesManager do
|
5
5
|
before(:all) do
|
6
6
|
assert_policy_state = proc do |policies, state|
|
7
|
-
expect(policies.keys.size).to eq(
|
7
|
+
expect(policies.keys.size).to eq(9)
|
8
8
|
|
9
9
|
policies.each_value do |policy|
|
10
10
|
next if policy.instance_of?(TCellAgent::Policies::LoginPolicy)
|
@@ -51,21 +51,21 @@ module TCellAgent
|
|
51
51
|
|
52
52
|
context 'nil enablements' do
|
53
53
|
it 'all policies should remain disabled' do
|
54
|
-
@policies_manager.process_policy_json(nil
|
54
|
+
@policies_manager.process_policy_json(nil)
|
55
55
|
@assert_all_policies_disabled.call(@policies_manager.policies)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
59
|
context 'empty enablements' do
|
60
60
|
it 'all policies should remain disabled' do
|
61
|
-
@policies_manager.process_policy_json({}
|
61
|
+
@policies_manager.process_policy_json({})
|
62
62
|
@assert_all_policies_disabled.call(@policies_manager.policies)
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
66
|
context 'empty enablements' do
|
67
67
|
it 'all policies should remain disabled' do
|
68
|
-
@policies_manager.process_policy_json({}
|
68
|
+
@policies_manager.process_policy_json({})
|
69
69
|
@assert_all_policies_disabled.call(@policies_manager.policies)
|
70
70
|
end
|
71
71
|
end
|
@@ -83,18 +83,7 @@ module TCellAgent
|
|
83
83
|
'login_success_enabled' => true,
|
84
84
|
'login_failed_enabled' => true
|
85
85
|
}
|
86
|
-
|
87
|
-
'dlp' => {
|
88
|
-
'policy_id' => 'policy-id',
|
89
|
-
'version' => 1,
|
90
|
-
'data' => {
|
91
|
-
'data_discovery' => {
|
92
|
-
'database_enabled' => true
|
93
|
-
}
|
94
|
-
}
|
95
|
-
}
|
96
|
-
}
|
97
|
-
@policies_manager.process_policy_json(enablements, policies_json)
|
86
|
+
@policies_manager.process_policy_json(enablements)
|
98
87
|
@assert_all_policies_enabled.call(@policies_manager.policies)
|
99
88
|
end
|
100
89
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'active_record'
|
4
|
+
require 'tcell_agent/rails/railties/tcell_agent_database_railties'
|
5
|
+
|
6
|
+
describe '.find_by_sql' do
|
7
|
+
before(:all) do
|
8
|
+
TCellAgentDatabaseRailtie.initializers[0].run
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'testing function arguments' do
|
12
|
+
it 'accepts args' do
|
13
|
+
klass = Class.new.extend(ActiveRecord::Querying)
|
14
|
+
|
15
|
+
expect(klass).to receive(:find_by_sql).and_call_original
|
16
|
+
expect(klass).to receive(:find_by_sql).and_call_original
|
17
|
+
expect(klass).to receive(:tcell_find_by_sql).and_call_original
|
18
|
+
expect(klass).to receive(:tcell_find_by_sql).and_call_original
|
19
|
+
|
20
|
+
expect do
|
21
|
+
klass.find_by_sql('SELECT * FROM table')
|
22
|
+
end.to raise_error(NameError)
|
23
|
+
|
24
|
+
expect do
|
25
|
+
klass.find_by_sql('SELECT * FROM table', [1])
|
26
|
+
end.to raise_error(NameError)
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'ruby 2' do
|
30
|
+
it 'accepts args and kwargs', :if => RUBY_VERSION.start_with?('2') do
|
31
|
+
klass = Class.new.extend(ActiveRecord::Querying)
|
32
|
+
|
33
|
+
expect(klass).to receive(:find_by_sql).and_call_original
|
34
|
+
expect(klass).to receive(:tcell_find_by_sql).and_call_original
|
35
|
+
|
36
|
+
expect do
|
37
|
+
klass.find_by_sql('SELECT * FROM table', [1], { :preparable => true })
|
38
|
+
end.to raise_error(NameError)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'ruby 3' do
|
43
|
+
it 'accepts args and kwargs', :if => RUBY_VERSION.start_with?('3') do
|
44
|
+
klass = Class.new.extend(ActiveRecord::Querying)
|
45
|
+
|
46
|
+
expect(klass).to receive(:find_by_sql).and_call_original
|
47
|
+
expect(klass).to receive(:find_by_sql).and_call_original
|
48
|
+
expect(klass).to receive(:tcell_find_by_sql).and_call_original
|
49
|
+
expect(klass).to receive(:tcell_find_by_sql).and_call_original
|
50
|
+
|
51
|
+
expect do
|
52
|
+
klass.find_by_sql('SELECT * FROM table', [1], :preparable => true)
|
53
|
+
end.to raise_error(NameError)
|
54
|
+
expect do
|
55
|
+
klass.find_by_sql('SELECT * FROM table', [1], **{ :preparable => true })
|
56
|
+
end.to raise_error(NameError)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -121,7 +121,7 @@ module TCellAgent
|
|
121
121
|
end
|
122
122
|
|
123
123
|
context 'that should be processed' do
|
124
|
-
it 'should call js
|
124
|
+
it 'should call js procs as well as calculate content length' do
|
125
125
|
js_agent_insertion_proc = double('js_agent_insertion_proc')
|
126
126
|
tcell_body_proxy = TCellBodyProxy.new(
|
127
127
|
Rack::BodyProxy.new(['some content']) {},
|
@@ -168,7 +168,7 @@ module TCellAgent
|
|
168
168
|
end
|
169
169
|
|
170
170
|
context 'that should be processed' do
|
171
|
-
it 'should call js
|
171
|
+
it 'should call js procs as well as calculate content length' do
|
172
172
|
body_chunk = 'some content'
|
173
173
|
js_agent_insertion_proc = double('js_agent_insertion_proc')
|
174
174
|
tcell_body_proxy = TCellBodyProxy.new(
|