tcell_agent 2.7.0 → 2.7.1
Sign up to get free protection for your applications and to get access to all the features.
- 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(
|