tcell_agent 0.2.29 → 0.4.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.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/Readme.txt +7 -0
  3. data/bin/tcell_agent +9 -0
  4. data/lib/tcell_agent/agent/policy_manager.rb +3 -0
  5. data/lib/tcell_agent/agent/policy_types.rb +4 -1
  6. data/lib/tcell_agent/appsensor/injections_matcher.rb +20 -0
  7. data/lib/tcell_agent/appsensor/injections_reporter.rb +15 -56
  8. data/lib/tcell_agent/appsensor/meta_data.rb +56 -2
  9. data/lib/tcell_agent/appsensor/rules/baserules.json +371 -138
  10. data/lib/tcell_agent/cmdi.rb +113 -0
  11. data/lib/tcell_agent/config/unknown_options.rb +2 -0
  12. data/lib/tcell_agent/configuration.rb +30 -16
  13. data/lib/tcell_agent/hooks/login_fraud.rb +79 -0
  14. data/lib/tcell_agent/instrumentation.rb +6 -11
  15. data/lib/tcell_agent/patches/meta_data.rb +14 -11
  16. data/lib/tcell_agent/policies/appsensor/injection_sensor.rb +5 -9
  17. data/lib/tcell_agent/policies/appsensor_policy.rb +22 -206
  18. data/lib/tcell_agent/policies/clickjacking_policy.rb +4 -2
  19. data/lib/tcell_agent/policies/command_injection_policy.rb +196 -0
  20. data/lib/tcell_agent/policies/content_security_policy.rb +3 -2
  21. data/lib/tcell_agent/policies/dataloss_policy.rb +3 -1
  22. data/lib/tcell_agent/policies/honeytokens_policy.rb +3 -1
  23. data/lib/tcell_agent/policies/http_redirect_policy.rb +51 -37
  24. data/lib/tcell_agent/policies/http_tx_policy.rb +5 -1
  25. data/lib/tcell_agent/policies/login_fraud_policy.rb +6 -1
  26. data/lib/tcell_agent/policies/patches_policy.rb +3 -1
  27. data/lib/tcell_agent/policies/policy.rb +10 -0
  28. data/lib/tcell_agent/policies/secure_headers_policy.rb +5 -2
  29. data/lib/tcell_agent/rails/auth/devise.rb +12 -23
  30. data/lib/tcell_agent/rails/csrf_exception.rb +1 -1
  31. data/lib/tcell_agent/rails/dlp.rb +50 -54
  32. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +0 -1
  33. data/lib/tcell_agent/rails/middleware/context_middleware.rb +0 -1
  34. data/lib/tcell_agent/rails/middleware/global_middleware.rb +0 -1
  35. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +7 -10
  36. data/lib/tcell_agent/rails/on_start.rb +0 -1
  37. data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -4
  38. data/lib/tcell_agent/rails.rb +0 -2
  39. data/lib/tcell_agent/rust/libtcellagent-0.6.1.dylib +0 -0
  40. data/lib/tcell_agent/rust/libtcellagent-0.6.1.so +0 -0
  41. data/lib/tcell_agent/rust/models.rb +61 -0
  42. data/lib/tcell_agent/rust/tcellagent-0.6.1.dll +0 -0
  43. data/lib/tcell_agent/rust/whisperer.rb +112 -0
  44. data/lib/tcell_agent/sensor_events/appsensor_event.rb +25 -21
  45. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +31 -24
  46. data/lib/tcell_agent/sensor_events/command_injection.rb +58 -0
  47. data/lib/tcell_agent/sensor_events/discovery.rb +1 -1
  48. data/lib/tcell_agent/sensor_events/login_fraud.rb +3 -13
  49. data/lib/tcell_agent/sensor_events/sensor.rb +81 -77
  50. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +8 -0
  51. data/lib/tcell_agent/start_background_thread.rb +12 -3
  52. data/lib/tcell_agent/utils/io.rb +4 -1
  53. data/lib/tcell_agent/utils/params.rb +1 -0
  54. data/lib/tcell_agent/version.rb +1 -1
  55. data/lib/tcell_agent.rb +0 -1
  56. data/spec/lib/tcell_agent/appsensor/injections_matcher_spec.rb +27 -9
  57. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +143 -193
  58. data/spec/lib/tcell_agent/appsensor/meta_data_spec.rb +67 -0
  59. data/spec/lib/tcell_agent/appsensor/rules/appsensor_rule_manager_spec.rb +0 -10
  60. data/spec/lib/tcell_agent/cmdi_spec.rb +748 -0
  61. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +8 -0
  62. data/spec/lib/tcell_agent/configuration_spec.rb +138 -6
  63. data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +357 -0
  64. data/spec/lib/tcell_agent/patches/block_rule_spec.rb +70 -87
  65. data/spec/lib/tcell_agent/patches_spec.rb +9 -4
  66. data/spec/lib/tcell_agent/policies/appsensor/xss_sensor_spec.rb +186 -9
  67. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +309 -484
  68. data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +736 -0
  69. data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +222 -41
  70. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +56 -32
  71. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +161 -85
  72. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +40 -72
  73. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +267 -0
  74. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +20 -15
  75. data/spec/spec_helper.rb +0 -9
  76. data/tcell_agent.gemspec +8 -3
  77. metadata +40 -39
  78. data/lib/tcell_agent/appsensor/sensor.rb +0 -52
  79. data/lib/tcell_agent/policies/appsensor/database_sensor.rb +0 -56
  80. data/lib/tcell_agent/policies/appsensor/misc_sensor.rb +0 -59
  81. data/lib/tcell_agent/policies/appsensor/payloads_policy.rb +0 -150
  82. data/lib/tcell_agent/policies/appsensor/request_size_sensor.rb +0 -25
  83. data/lib/tcell_agent/policies/appsensor/response_codes_sensor.rb +0 -73
  84. data/lib/tcell_agent/policies/appsensor/response_size_sensor.rb +0 -25
  85. data/lib/tcell_agent/policies/appsensor/size_sensor.rb +0 -71
  86. data/lib/tcell_agent/policies/appsensor/user_agent_sensor.rb +0 -47
  87. data/lib/tcell_agent/rails/auth/hooks.rb +0 -79
  88. data/lib/tcell_agent/sensor_events/util/redirect_utils.rb +0 -22
  89. data/spec/lib/tcell_agent/policies/appsensor/database_sensor_spec.rb +0 -165
  90. data/spec/lib/tcell_agent/policies/appsensor/misc_sensor_spec.rb +0 -429
  91. data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_apply_spec.rb +0 -466
  92. data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_from_json_spec.rb +0 -890
  93. data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_log_spec.rb +0 -417
  94. data/spec/lib/tcell_agent/policies/appsensor/request_size_sensor_spec.rb +0 -236
  95. data/spec/lib/tcell_agent/policies/appsensor/response_codes_sensor_spec.rb +0 -297
  96. data/spec/lib/tcell_agent/policies/appsensor/response_size_sensor_spec.rb +0 -241
  97. data/spec/lib/tcell_agent/policies/appsensor/user_agent_sensor_spec.rb +0 -172
  98. data/spec/lib/tcell_agent/rails/auth/hooks_spec.rb +0 -246
  99. data/spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb +0 -25
  100. data/spec/support/resources/baserules.json +0 -155
@@ -1,6 +1,9 @@
1
+ require 'tcell_agent/policies/policy'
2
+
3
+
1
4
  module TCellAgent
2
5
  module Policies
3
- class LoginFraudPolicy
6
+ class LoginFraudPolicy < Policy
4
7
  attr_accessor :policy_id
5
8
 
6
9
  attr_accessor :login_success_enabled
@@ -16,9 +19,11 @@ module TCellAgent
16
19
  @login_failed_enabled = false
17
20
  @session_hijacking_metrics = false
18
21
  end
22
+
19
23
  def enabled
20
24
  @login_success_enabled || @login_failed_enabled
21
25
  end
26
+
22
27
  def self.from_json(policy_json)
23
28
  if (!policy_json)
24
29
  return nil
@@ -1,11 +1,13 @@
1
1
  require 'tcell_agent/appsensor/injections_matcher'
2
2
  require 'tcell_agent/patches/block_rule'
3
3
  require 'tcell_agent/patches/sensors_matcher'
4
+ require 'tcell_agent/policies/policy'
5
+
4
6
 
5
7
  module TCellAgent
6
8
  module Policies
7
9
 
8
- class PatchesPolicy
10
+ class PatchesPolicy < Policy
9
11
  attr_accessor :policy_id, :version, :enabled, :block_rules
10
12
 
11
13
  def initialize
@@ -0,0 +1,10 @@
1
+ module TCellAgent
2
+ module Policies
3
+
4
+ class Policy
5
+ def free_native_memory
6
+ end
7
+ end
8
+
9
+ end
10
+ end
@@ -1,8 +1,11 @@
1
1
  # encoding: utf-8
2
2
  # See the file "LICENSE" for the full license governing this code.
3
+ require 'tcell_agent/policies/policy'
4
+
5
+
3
6
  module TCellAgent
4
7
  module Policies
5
- class SecureHeadersPolicy
8
+ class SecureHeadersPolicy < Policy
6
9
  class SecurityHeader
7
10
  @@approved_headers = [
8
11
  "strict-transport-security",
@@ -33,7 +36,7 @@ module TCellAgent
33
36
  attr_accessor :policy_id
34
37
 
35
38
  def self.from_json(policy_json)
36
- if (!policy_json)
39
+ if (!policy_json)
37
40
  return nil
38
41
  end
39
42
  security_headers_policy = SecureHeadersPolicy.new
@@ -7,19 +7,6 @@ if TCellAgent.configuration.should_instrument_devise? && defined?(Devise)
7
7
  require 'tcell_agent/policies/appsensor_policy'
8
8
 
9
9
  module DeviseInstrumentation
10
- def self.report_login_event(clazz, request_env, user_id)
11
- if (TCellAgent.configuration.enabled && TCellAgent.configuration.should_intercept_requests?)
12
-
13
- login_fraud_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LoginFraud)
14
- if (login_fraud_policy && login_fraud_policy.enabled && login_fraud_policy.login_failed_enabled)
15
- tcell_data = request_env[TCellAgent::Instrumentation::TCELL_ID]
16
- if tcell_data
17
- TCellAgent.send_event(clazz.new(request_env, tcell_data, user_id))
18
- end
19
- end
20
- end
21
- end
22
-
23
10
  module TCellFailureAppRespond
24
11
  def respond
25
12
  TCellAgent::Instrumentation.safe_block("Devise Failure App Respond") do
@@ -30,11 +17,11 @@ if TCellAgent.configuration.should_instrument_devise? && defined?(Devise)
30
17
  # Devise::Strategies::Authenticatable.valid_for_http_auth?
31
18
  user_id = tcell_data.user_id
32
19
  user_id = _get_tcell_username unless user_id
33
- TCellAgent::DeviseInstrumentation.report_login_event(
34
- TCellAgent::SensorEvents::LoginFailure,
35
- request.env,
36
- user_id
37
- )
20
+
21
+ login_fraud_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LoginFraud)
22
+ if (login_fraud_policy && login_fraud_policy.login_failed_enabled)
23
+ TCellAgent.send_event(TCellAgent::SensorEvents::LoginFailure.new(request.env, tcell_data, user_id))
24
+ end
38
25
  end
39
26
 
40
27
  end
@@ -95,11 +82,13 @@ if TCellAgent.configuration.should_instrument_devise? && defined?(Devise)
95
82
  end
96
83
  end
97
84
 
98
- TCellAgent::DeviseInstrumentation.report_login_event(
99
- TCellAgent::SensorEvents::LoginSuccess,
100
- request.env,
101
- username
102
- )
85
+ login_fraud_policy = TCellAgent.policy(TCellAgent::PolicyTypes::LoginFraud)
86
+ if (login_fraud_policy && login_fraud_policy.login_success_enabled)
87
+ tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
88
+ if tcell_data
89
+ TCellAgent.send_event(TCellAgent::SensorEvents::LoginSuccess.new(request.env, tcell_data, username))
90
+ end
91
+ end
103
92
  end
104
93
  end
105
94
 
@@ -9,7 +9,7 @@ module TCellAgent
9
9
  if appsensor_policy
10
10
  tcell_data = request.env[TCellAgent::Instrumentation::TCELL_ID]
11
11
  if tcell_data
12
- appsensor_policy.csrf_rejected(tcell_data, ActionController::InvalidAuthenticityToken)
12
+ tcell_data.csrf_exception_name = ActionController::InvalidAuthenticityToken.name
13
13
  end
14
14
  end
15
15
  end
@@ -10,7 +10,6 @@ require 'tcell_agent/agent'
10
10
  require 'tcell_agent/sensor_events/sensor'
11
11
  require 'tcell_agent/sensor_events/server_agent'
12
12
  require 'tcell_agent/sensor_events/util/sanitizer_utilities'
13
- require 'tcell_agent/sensor_events/util/redirect_utils'
14
13
 
15
14
  require 'tcell_agent/sensor_events/dlp'
16
15
 
@@ -41,67 +40,62 @@ module TCellAgent
41
40
  TCellAgent.configuration.should_intercept_requests?
42
41
 
43
42
  dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
44
- appsensor_policy = TCellAgent.policy(TCellAgent::PolicyTypes::AppSensor)
45
43
 
46
- if dlp_policy || appsensor_policy
47
- request_env = TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware::THREADS.fetch(Thread.current.object_id, {})
48
- tcell_context = request_env[TCellAgent::Instrumentation::TCELL_ID]
44
+ request_env = TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware::THREADS.fetch(Thread.current.object_id, {})
45
+ tcell_context = request_env[TCellAgent::Instrumentation::TCELL_ID]
49
46
 
50
- if tcell_context
51
- if appsensor_policy
52
- appsensor_policy.process_db_rows(tcell_context, results.size)
53
- end
47
+ if tcell_context
48
+ tcell_context.database_result_sizes.push(results.size)
54
49
 
55
- if dlp_policy
56
- first_record = results.first
57
- database_name = first_record.class.connection_config().fetch(:database,"*").split('/').last
58
- model = first_record.class
59
- column_names = model.columns.map { |col| col.name }
60
- table_name = model.table_name
50
+ if dlp_policy
51
+ first_record = results.first
52
+ database_name = first_record.class.connection_config().fetch(:database,"*").split('/').last
53
+ model = first_record.class
54
+ column_names = model.columns.map { |col| col.name }
55
+ table_name = model.table_name
61
56
 
62
- if dlp_policy.database_discovery_enabled
63
- TCellAgent.discover_database_fields(
64
- tcell_context.route_id,
65
- database_name,
66
- "*",
67
- table_name,
68
- column_names
69
- )
70
- end
57
+ if dlp_policy.database_discovery_enabled
58
+ TCellAgent.discover_database_fields(
59
+ tcell_context.route_id,
60
+ database_name,
61
+ "*",
62
+ table_name,
63
+ column_names
64
+ )
65
+ end
71
66
 
72
- if results.size > TCellAgent.configuration.max_data_ex_db_records_per_request
73
- TCellAgent.logger.warn("Route (#{tcell_context.route_id}) retrieved too many records")
74
- end
67
+ if results.size > TCellAgent.configuration.max_data_ex_db_records_per_request
68
+ TCellAgent.logger.warn("Route (#{tcell_context.route_id}) retrieved too many records")
69
+ end
75
70
 
76
- column_name_to_rules = column_names.inject({}) do |memo, column_name|
77
- rules = dlp_policy.get_actions_for_table(
78
- database_name,
79
- "*",
80
- table_name,
81
- column_name,
82
- tcell_context.route_id
83
- )
71
+ column_name_to_rules = column_names.inject({}) do |memo, column_name|
72
+ rules = dlp_policy.get_actions_for_table(
73
+ database_name,
74
+ "*",
75
+ table_name,
76
+ column_name,
77
+ tcell_context.route_id
78
+ )
84
79
 
85
- memo[column_name] = rules if rules
80
+ memo[column_name] = rules if rules
86
81
 
87
- memo
88
- end
82
+ memo
83
+ end
89
84
 
90
- return if column_name_to_rules.empty?
91
-
92
- results[0...TCellAgent.configuration.max_data_ex_db_records_per_request].each do |record|
93
- column_name_to_rules.each do |column_name, rules|
94
- if rules
95
- rules.each do |rule|
96
- tcell_context.add_response_db_filter(
97
- record[column_name.to_sym],
98
- rule,
99
- database_name,
100
- "*",
101
- table_name,
102
- column_name
103
- )
104
- end
85
+ return if column_name_to_rules.empty?
86
+
87
+ results[0...TCellAgent.configuration.max_data_ex_db_records_per_request].each do |record|
88
+ column_name_to_rules.each do |column_name, rules|
89
+ if rules
90
+ rules.each do |rule|
91
+ tcell_context.add_response_db_filter(
92
+ record[column_name.to_sym],
93
+ rule,
94
+ database_name,
95
+ "*",
96
+ table_name,
97
+ column_name
98
+ )
105
99
  end
106
100
  end
107
101
  end
@@ -128,7 +122,9 @@ module TCellAgent
128
122
  request_env = TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware::THREADS.fetch(Thread.current.object_id, {})
129
123
  tcell_data = request_env[TCellAgent::Instrumentation::TCELL_ID]
130
124
  if tcell_data && result.is_a?(ActiveRecord::StatementInvalid)
131
- appsensor_policy.sql_exception_detected(tcell_data, result)
125
+ tcell_data.sql_exceptions.push({
126
+ "exception_name" => result.class.name, "exception_payload" => message
127
+ })
132
128
  end
133
129
  end
134
130
  end
@@ -7,7 +7,6 @@ require 'tcell_agent/agent'
7
7
  require 'tcell_agent/sensor_events/sensor'
8
8
  require 'tcell_agent/sensor_events/server_agent'
9
9
  require 'tcell_agent/sensor_events/util/sanitizer_utilities'
10
- require 'tcell_agent/sensor_events/util/redirect_utils'
11
10
 
12
11
  require 'tcell_agent/configuration'
13
12
  require 'tcell_agent/instrumentation'
@@ -7,7 +7,6 @@ require 'tcell_agent/agent'
7
7
  require 'tcell_agent/sensor_events/sensor'
8
8
  require 'tcell_agent/sensor_events/server_agent'
9
9
  require 'tcell_agent/sensor_events/util/sanitizer_utilities'
10
- require 'tcell_agent/sensor_events/util/redirect_utils'
11
10
 
12
11
  require 'tcell_agent/userinfo'
13
12
  require 'cgi'
@@ -7,7 +7,6 @@ require 'tcell_agent/agent'
7
7
  require 'tcell_agent/sensor_events/sensor'
8
8
  require 'tcell_agent/sensor_events/server_agent'
9
9
  require 'tcell_agent/sensor_events/util/sanitizer_utilities'
10
- require 'tcell_agent/sensor_events/util/redirect_utils'
11
10
 
12
11
  require 'tcell_agent/userinfo'
13
12
  require 'cgi'
@@ -7,7 +7,6 @@ require 'tcell_agent/sensor_events/sensor'
7
7
  require 'tcell_agent/sensor_events/appsensor_meta_event'
8
8
  require 'tcell_agent/sensor_events/server_agent'
9
9
  require 'tcell_agent/sensor_events/util/sanitizer_utilities'
10
- require 'tcell_agent/sensor_events/util/redirect_utils'
11
10
 
12
11
  require 'tcell_agent/userinfo'
13
12
  require 'cgi'
@@ -118,12 +117,11 @@ module TCellAgent
118
117
  status, headers, active_response = response
119
118
  http_redirect_policy = TCellAgent.policy(TCellAgent::PolicyTypes::HttpRedirect)
120
119
  if http_redirect_policy && headers.has_key?("Location")
121
- local_uri = URI.parse(request.url)
122
120
  route_id = request.env[TCellAgent::Instrumentation::TCELL_ID].route_id
123
121
  hmac_session_id = request.env[TCellAgent::Instrumentation::TCELL_ID].hmac_session_id
124
122
  new_location = http_redirect_policy.enforce(
125
123
  headers["Location"],
126
- local_uri.host,
124
+ request.url,
127
125
  request.fullpath,
128
126
  request.request_method,
129
127
  route_id,
@@ -150,7 +148,7 @@ module TCellAgent
150
148
  TCellAgent::Instrumentation::Rails::DLPHandler.get_handler_and_context(request, response_headers)
151
149
 
152
150
  content_length = 0
153
- set_basic_appsensor_meta = false
151
+ defer_appfw_due_to_streaming = false
154
152
 
155
153
  if TCellAgent::Utils::Rails.empty_content?(status_code, response_headers)
156
154
  content_length = 0
@@ -184,7 +182,7 @@ module TCellAgent
184
182
  script_insert,
185
183
  dlp_handler,
186
184
  tcell_context)
187
- set_basic_appsensor_meta = true
185
+ defer_appfw_due_to_streaming = true
188
186
  end
189
187
 
190
188
  appsensor_policy = TCellAgent.policy(TCellAgent::PolicyTypes::AppSensor)
@@ -192,11 +190,10 @@ module TCellAgent
192
190
  event = TCellAgent::SensorEvents::AppSensorMetaEvent.build(
193
191
  request, content_length, status_code, response_headers
194
192
  )
195
- TCellAgent.send_event(event)
196
-
197
- if set_basic_appsensor_meta
198
- response_body.appsensor_policy = appsensor_policy
199
- response_body.appsensor_meta = TCellAgent::SensorEvents::AppSensorMetaEvent.build_basic(event)
193
+ if defer_appfw_due_to_streaming
194
+ response_body.appsensor_meta = event
195
+ else
196
+ TCellAgent.send_event(event)
200
197
  end
201
198
  end
202
199
 
@@ -27,7 +27,6 @@ else
27
27
  require 'tcell_agent/authlogic' if defined?(Authlogic)
28
28
  require 'tcell_agent/rails/auth/authlogic' if defined?(Authlogic)
29
29
  require 'tcell_agent/rails/auth/doorkeeper'
30
- require 'tcell_agent/rails/auth/hooks'
31
30
  end
32
31
 
33
32
  # TODO: will this get run ever?
@@ -6,7 +6,7 @@ module TCellAgent
6
6
 
7
7
  class TCellBodyProxy
8
8
 
9
- attr_accessor :appsensor_policy, :appsensor_meta
9
+ attr_accessor :appsensor_meta
10
10
 
11
11
  # for specs
12
12
  attr_accessor :content_length
@@ -30,10 +30,10 @@ module TCellAgent
30
30
  end
31
31
 
32
32
  def close
33
- TCellAgent::Instrumentation.safe_block("Handling Response Size Length") do
34
- if @content_length > 0 && @appsensor_meta && @appsensor_policy
33
+ TCellAgent::Instrumentation.safe_block("Running AppSensor deferred due to streaming") do
34
+ if @appsensor_meta
35
35
  @appsensor_meta.response_content_bytes_len = @content_length
36
- @appsensor_policy.check_response_size(@appsensor_meta)
36
+ TCellAgent.send_event(@appsensor_meta)
37
37
  end
38
38
  end
39
39
 
@@ -6,7 +6,6 @@ require 'tcell_agent/agent'
6
6
  require 'tcell_agent/sensor_events/sensor'
7
7
  require 'tcell_agent/sensor_events/server_agent'
8
8
  require 'tcell_agent/sensor_events/util/sanitizer_utilities'
9
- require 'tcell_agent/sensor_events/util/redirect_utils'
10
9
 
11
10
  require 'tcell_agent/rails/better_ip'
12
11
  require 'tcell_agent/rails/middleware/global_middleware'
@@ -32,7 +31,6 @@ module TCellAgent
32
31
  require 'tcell_agent/authlogic' if defined?(Authlogic)
33
32
  require 'tcell_agent/rails/auth/authlogic' if defined?(Authlogic)
34
33
  require 'tcell_agent/rails/auth/doorkeeper'
35
- require 'tcell_agent/rails/auth/hooks'
36
34
  end
37
35
  app.config.middleware.insert_before(0, TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware)
38
36
  app.config.middleware.insert_after(0, TCellAgent::Instrumentation::Rails::Middleware::HeadersMiddleware)
@@ -0,0 +1,61 @@
1
+ require 'tcell_agent/utils/strings'
2
+
3
+
4
+ module TCellAgent
5
+ module Rust
6
+ module Models
7
+
8
+ def self.convert_params(params_dict)
9
+ unless params_dict
10
+ return []
11
+ end
12
+
13
+ flattened_params = []
14
+ params_dict.each do |param_name, param_value|
15
+ flattened_params.push({"name" => param_name[-1], "value" => param_value})
16
+ end
17
+
18
+ flattened_params
19
+ end
20
+
21
+ def self.create_request_response(appsensor_meta)
22
+ post_params = convert_params(appsensor_meta.flattened_post_dict) +
23
+ convert_params(appsensor_meta.flattened_body_dict)
24
+
25
+ request_response = {
26
+ "method" => appsensor_meta.method,
27
+ "status_code" => appsensor_meta.response_code,
28
+ "route_id" => appsensor_meta.route_id,
29
+ "path" => appsensor_meta.path,
30
+ "query_params" => convert_params(appsensor_meta.flattened_get_dict),
31
+ "post_params" => post_params,
32
+ "headers" => convert_params(appsensor_meta.flattened_headers_dict),
33
+ "cookies" => convert_params(appsensor_meta.flattened_cookie_dict),
34
+ "path_params" => convert_params(appsensor_meta.flattened_path_parameters),
35
+ "remote_address" => appsensor_meta.remote_address,
36
+ "full_uri" => appsensor_meta.location,
37
+ "session_id" => appsensor_meta.session_id,
38
+ "user_id" => appsensor_meta.user_id,
39
+ "user_agent" => appsensor_meta.user_agent,
40
+ "request_bytes_length" => appsensor_meta.request_content_bytes_len,
41
+ "response_bytes_length" => appsensor_meta.response_content_bytes_len
42
+ }
43
+
44
+ if TCellAgent::Utils::Strings.present?(appsensor_meta.csrf_exception_name)
45
+ request_response["csrf_exception"] = {"exception_name" => appsensor_meta.csrf_exception_name}
46
+ end
47
+
48
+ if appsensor_meta.sql_exceptions
49
+ request_response["sql_exceptions"] = appsensor_meta.sql_exceptions
50
+ end
51
+
52
+ if appsensor_meta.database_result_sizes
53
+ request_response["database_result_sizes"] = appsensor_meta.database_result_sizes
54
+ end
55
+
56
+ return request_response
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,112 @@
1
+ require 'tcell_agent/logger'
2
+
3
+
4
+ module TCellAgent
5
+ module Rust
6
+ require "ffi"
7
+
8
+ module Wrapper
9
+ extend FFI::Library
10
+
11
+ begin
12
+ VERSION = "0.6.1"
13
+ prefix = "lib"
14
+ extension = ".so"
15
+ if /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
16
+ extension = ".dll"
17
+ prefix = ""
18
+ elsif /darwin/ =~ RUBY_PLATFORM
19
+ extension = ".dylib"
20
+ end
21
+
22
+ ffi_lib File.join(File.dirname(__FILE__), "#{prefix}tcellagent-#{VERSION}#{extension}")
23
+ attach_function :cmdi_parse_sh, [:pointer, :size_t, :pointer, :size_t], :int
24
+
25
+ attach_function :appfirewall_policy_init, [:pointer, :size_t, :pointer, :size_t, :pointer, :size_t], :int
26
+ attach_function :appfirewall_policy_apply, [:pointer, :pointer, :size_t, :pointer, :size_t], :int
27
+ attach_function :appfirewall_free, [:pointer], :void
28
+
29
+ def self.common_lib_available?
30
+ true
31
+ end
32
+
33
+ rescue LoadError => load_error
34
+ puts "tCell.io Failed to load common agent library. #{load_error.message}"
35
+ TCellAgent.logger.error("Failed to load common agent library. #{load_error.message}")
36
+ TCellAgent.logger.debug(load_error.backtrace)
37
+ def self.common_lib_available?
38
+ false
39
+ end
40
+ end
41
+ end
42
+
43
+ module Whisperer
44
+ def self.convert_result(result_size, result)
45
+ begin
46
+ return JSON.parse(result.get_string(0, result_size)) if result_size >= 0
47
+ rescue JSON::ParserError
48
+ # don't log the actual error since it might contain payload information
49
+ TCellAgent.logger.error("JSON::ParserError ocurred when trying to parse native lib response")
50
+ end
51
+
52
+ return {}
53
+ end
54
+
55
+ def self.parse_cmd(cmd)
56
+ if TCellAgent::Rust::Wrapper.common_lib_available? &&
57
+ TCellAgent::Utils::Strings.present?(cmd)
58
+ cmd_pointer = FFI::MemoryPointer.from_string(cmd)
59
+
60
+ buf = FFI::MemoryPointer.new(:uint8, 1024 * 8)
61
+
62
+ # cmd_pointer.size - 1: strips null terminator
63
+ result_size = TCellAgent::Rust::Wrapper.cmdi_parse_sh(cmd_pointer, cmd_pointer.size - 1, buf, buf.size)
64
+ return self.convert_result(result_size, buf)
65
+ end
66
+
67
+ return {}
68
+ end
69
+
70
+ def self.init_appfirewall(policy, allow_payloads)
71
+ if TCellAgent::Rust::Wrapper.common_lib_available? && policy
72
+ policy_pointer = FFI::MemoryPointer.from_string(JSON.dump(policy))
73
+ config_pointer = FFI::MemoryPointer.from_string(JSON.dump({"allow_send_payloads" => allow_payloads}))
74
+
75
+ buf = FFI::MemoryPointer.new(:uint8, 1024 * 8)
76
+ # policy_pointer.size - 1: strips null terminator
77
+ # config_pointer.size - 1: strips null terminator
78
+ result_size = TCellAgent::Rust::Wrapper.appfirewall_policy_init(
79
+ policy_pointer, policy_pointer.size - 1, config_pointer, config_pointer.size - 1, buf, buf.size
80
+ )
81
+ return self.convert_result(result_size, buf)
82
+ end
83
+
84
+ return {}
85
+ end
86
+
87
+ def self.apply_appfirewall(appfirewall_ptr, request_response_json)
88
+ if TCellAgent::Rust::Wrapper.common_lib_available? &&
89
+ request_response_json &&
90
+ !appfirewall_ptr.nil?
91
+ request_response_pointer = FFI::MemoryPointer.from_string(JSON.dump(request_response_json))
92
+
93
+ buf = FFI::MemoryPointer.new(:uint8, 1024 * 8)
94
+ # request_response_pointer.size - 1: strips null terminator
95
+ result_size = TCellAgent::Rust::Wrapper.appfirewall_policy_apply(
96
+ FFI::Pointer.new(appfirewall_ptr), request_response_pointer, request_response_pointer.size - 1, buf, buf.size
97
+ )
98
+ return self.convert_result(result_size, buf)
99
+ end
100
+
101
+ return {}
102
+ end
103
+
104
+
105
+ def self.free_appfirewall(appfirewall_ptr)
106
+ if TCellAgent::Rust::Wrapper.common_lib_available? && !appfirewall_ptr.nil?
107
+ TCellAgent::Rust::Wrapper.appfirewall_free(FFI::Pointer.new(appfirewall_ptr))
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -3,13 +3,11 @@ require 'tcell_agent/sensor_events/sensor'
3
3
 
4
4
  module TCellAgent
5
5
  module SensorEvents
6
-
7
6
  class TCellAppSensorEvent < TCellSensorEvent
8
-
9
7
  def initialize(location,
10
8
  detection_point,
11
9
  method,
12
- remote_addr,
10
+ remote_address,
13
11
  param,
14
12
  route_id,
15
13
  meta,
@@ -17,33 +15,39 @@ module TCellAgent
17
15
  user_id,
18
16
  payload,
19
17
  pattern,
20
- collect_full_uri)
18
+ full_uri)
21
19
  super("as")
22
20
  self["dp"] = detection_point
21
+
23
22
  self["param"] = param.to_s if param
24
- self["remote_addr"] = remote_addr.to_s if remote_addr
25
23
  self["m"] = method.to_s if method
26
- @raw_location = location
27
- @user_id = user_id
28
- @hmac_session_id = hmac_session_id
29
- @payload = payload
30
-
31
24
  self["pattern"] = pattern if pattern
32
25
  self["meta"] = meta if meta
33
- self["rid"] = route_id if route_id
34
- self["full_uri"] = location if collect_full_uri && location
26
+ self["rid"] = route_id.to_s if route_id
27
+ self["full_uri"] = full_uri if full_uri
28
+ self["uri"] = location if location
29
+ self["uid"] = user_id.to_s if user_id
30
+ self["sid"] = hmac_session_id if hmac_session_id
31
+ self["remote_addr"] = remote_address.to_s if remote_address
32
+ self["payload"] = payload if payload
35
33
  end
36
34
 
37
- def post_process
38
- self["uri"] = Util.strip_uri_values(@raw_location)
39
- self["uid"] = @user_id.to_s if @user_id
40
- if @hmac_session_id
41
- self["sid"] = @hmac_session_id
42
- end
43
- self["payload"] = @payload[0..150] if @payload
35
+ def self.build_from_native_lib_event(event)
36
+ return TCellAppSensorEvent.new(
37
+ event["uri"],
38
+ event["detection_point"],
39
+ event["method"],
40
+ event["remote_address"],
41
+ event["parameter"],
42
+ event["route_id"],
43
+ event["meta"],
44
+ event["session_id"],
45
+ event["user_id"],
46
+ event["payload"],
47
+ event["pattern"],
48
+ event["full_uri"]
49
+ )
44
50
  end
45
-
46
51
  end
47
-
48
52
  end
49
53
  end