tcell_agent 1.1.12 → 2.0.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 (163) hide show
  1. checksums.yaml +5 -5
  2. data/bin/tcell_agent +26 -14
  3. data/lib/tcell_agent.rb +16 -10
  4. data/lib/tcell_agent/agent.rb +78 -97
  5. data/lib/tcell_agent/agent/route_manager.rb +0 -16
  6. data/lib/tcell_agent/agent/static_agent.rb +9 -30
  7. data/lib/tcell_agent/authlogic.rb +3 -6
  8. data/lib/tcell_agent/config/unknown_options.rb +4 -8
  9. data/lib/tcell_agent/configuration.rb +38 -119
  10. data/lib/tcell_agent/devise.rb +25 -27
  11. data/lib/tcell_agent/hooks/login_fraud.rb +30 -33
  12. data/lib/tcell_agent/instrument_servers.rb +25 -0
  13. data/lib/tcell_agent/instrumentation.rb +12 -10
  14. data/lib/tcell_agent/instrumentation/cmdi.rb +19 -15
  15. data/lib/tcell_agent/instrumentation/lfi.rb +73 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +25 -0
  17. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +123 -0
  18. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +159 -0
  19. data/lib/tcell_agent/logger.rb +50 -114
  20. data/lib/tcell_agent/patches.rb +6 -7
  21. data/lib/tcell_agent/policies/appfirewall_policy.rb +26 -0
  22. data/lib/tcell_agent/policies/command_injection_policy.rb +28 -0
  23. data/lib/tcell_agent/policies/dataloss_policy.rb +44 -44
  24. data/lib/tcell_agent/policies/headers_policy.rb +25 -0
  25. data/lib/tcell_agent/policies/http_redirect_policy.rb +13 -79
  26. data/lib/tcell_agent/policies/js_agent_policy.rb +27 -0
  27. data/lib/tcell_agent/policies/local_file_access.rb +28 -0
  28. data/lib/tcell_agent/policies/login_policy.rb +43 -0
  29. data/lib/tcell_agent/policies/patches_policy.rb +27 -0
  30. data/lib/tcell_agent/policies/policies_manager.rb +68 -0
  31. data/lib/tcell_agent/policies/policy_polling.rb +58 -0
  32. data/lib/tcell_agent/policies/policy_types.rb +14 -0
  33. data/lib/tcell_agent/policies/system_enablements.rb +27 -0
  34. data/lib/tcell_agent/rails/auth/authlogic.rb +43 -68
  35. data/lib/tcell_agent/rails/auth/devise.rb +20 -23
  36. data/lib/tcell_agent/rails/auth/doorkeeper.rb +63 -74
  37. data/lib/tcell_agent/rails/csrf_exception.rb +2 -2
  38. data/lib/tcell_agent/rails/dlp.rb +25 -15
  39. data/lib/tcell_agent/rails/dlp_handler.rb +1 -2
  40. data/lib/tcell_agent/rails/js_agent_insert.rb +12 -13
  41. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +4 -25
  42. data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -12
  43. data/lib/tcell_agent/rails/middleware/global_middleware.rb +0 -1
  44. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +14 -34
  45. data/lib/tcell_agent/rails/on_start.rb +32 -31
  46. data/lib/tcell_agent/rails/routes.rb +7 -6
  47. data/lib/tcell_agent/rails/routes/grape.rb +1 -3
  48. data/lib/tcell_agent/rails/routes/route_id.rb +3 -1
  49. data/lib/tcell_agent/rails/settings_reporter.rb +23 -36
  50. data/lib/tcell_agent/rails/start_agent_after_initializers.rb +12 -0
  51. data/lib/tcell_agent/rails/tcell_body_proxy.rb +6 -4
  52. data/lib/tcell_agent/rust/agent_config.rb +49 -0
  53. data/lib/tcell_agent/rust/{libtcellagent-alpine-1.3.2.so → libtcellagent-4.14.0.dylib} +0 -0
  54. data/lib/tcell_agent/rust/libtcellagent-4.14.0.so +0 -0
  55. data/lib/tcell_agent/rust/{libtcellagent-1.3.2.so → libtcellagent-alpine-4.14.0.so} +0 -0
  56. data/lib/tcell_agent/rust/models.rb +0 -55
  57. data/lib/tcell_agent/rust/native_agent.rb +531 -0
  58. data/lib/tcell_agent/rust/native_agent_response.rb +42 -0
  59. data/lib/tcell_agent/rust/native_library.rb +68 -0
  60. data/lib/tcell_agent/rust/tcellagent-4.14.0.dll +0 -0
  61. data/lib/tcell_agent/sensor_events/agent_setting_event.rb +12 -0
  62. data/lib/tcell_agent/sensor_events/{app_config.rb → app_config_setting_event.rb} +0 -6
  63. data/lib/tcell_agent/sensor_events/dlp.rb +2 -6
  64. data/lib/tcell_agent/sensor_events/sensor.rb +0 -62
  65. data/lib/tcell_agent/sensor_events/server_agent.rb +13 -18
  66. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +0 -108
  67. data/lib/tcell_agent/sensor_events/util/utils.rb +0 -2
  68. data/lib/tcell_agent/servers/passenger.rb +1 -28
  69. data/lib/tcell_agent/servers/puma.rb +3 -21
  70. data/lib/tcell_agent/servers/rails_server.rb +1 -1
  71. data/lib/tcell_agent/servers/thin.rb +2 -2
  72. data/lib/tcell_agent/servers/unicorn.rb +19 -80
  73. data/lib/tcell_agent/servers/webrick.rb +1 -1
  74. data/lib/tcell_agent/settings_reporter.rb +24 -24
  75. data/lib/tcell_agent/sinatra.rb +14 -16
  76. data/lib/tcell_agent/tcell_context.rb +40 -14
  77. data/lib/tcell_agent/utils/headers.rb +14 -0
  78. data/lib/tcell_agent/version.rb +1 -1
  79. data/spec/lib/tcell_agent/cmdi_spec.rb +0 -585
  80. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -18
  81. data/spec/lib/tcell_agent/configuration_spec.rb +4 -140
  82. data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +46 -173
  83. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +504 -0
  84. data/spec/lib/tcell_agent/instrumentation/cmdi/kernel_cmdi_spec.rb +435 -0
  85. data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +326 -0
  86. data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +556 -0
  87. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +249 -0
  88. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +105 -0
  89. data/spec/lib/tcell_agent/patches_spec.rb +25 -43
  90. data/spec/lib/tcell_agent/policies/appfirewall_policy_spec.rb +183 -0
  91. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +57 -0
  92. data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +84 -773
  93. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +161 -0
  94. data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +9 -9
  95. data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +243 -198
  96. data/spec/lib/tcell_agent/policies/js_agent_policy_spec.rb +75 -0
  97. data/spec/lib/tcell_agent/policies/login_policy_spec.rb +165 -33
  98. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +84 -277
  99. data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +104 -0
  100. data/spec/lib/tcell_agent/policies/policy_polling_spec.rb +6 -0
  101. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +56 -0
  102. data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +9 -18
  103. data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +13 -30
  104. data/spec/lib/tcell_agent/rails/logger_spec.rb +27 -7
  105. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +17 -12
  106. data/spec/lib/tcell_agent/rails/routes/routes_spec.rb +14 -14
  107. data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +0 -35
  108. data/spec/lib/tcell_agent/settings_reporter_spec.rb +127 -153
  109. data/spec/spec_helper.rb +1 -1
  110. data/spec/support/builders.rb +104 -0
  111. data/spec/support/force_logger_mocking.rb +38 -0
  112. data/spec/support/resources/lfi_sample_file.txt +2 -0
  113. data/spec/support/static_agent_overrides.rb +0 -15
  114. metadata +63 -74
  115. data/lib/tcell_agent/agent/event_processor.rb +0 -326
  116. data/lib/tcell_agent/agent/fork_pipe_manager.rb +0 -113
  117. data/lib/tcell_agent/agent/policy_manager.rb +0 -219
  118. data/lib/tcell_agent/agent/policy_types.rb +0 -30
  119. data/lib/tcell_agent/api.rb +0 -91
  120. data/lib/tcell_agent/appsensor/injections_reporter.rb +0 -24
  121. data/lib/tcell_agent/config/child_process_events.rb +0 -8
  122. data/lib/tcell_agent/instrumentation/cmdi/backtick.rb +0 -10
  123. data/lib/tcell_agent/instrumentation/cmdi/exec.rb +0 -14
  124. data/lib/tcell_agent/instrumentation/cmdi/popen.rb +0 -28
  125. data/lib/tcell_agent/instrumentation/cmdi/spawn.rb +0 -11
  126. data/lib/tcell_agent/instrumentation/cmdi/system.rb +0 -11
  127. data/lib/tcell_agent/policies/http_tx_policy.rb +0 -60
  128. data/lib/tcell_agent/policies/login_fraud_policy.rb +0 -45
  129. data/lib/tcell_agent/policies/rust_policies.rb +0 -110
  130. data/lib/tcell_agent/rails.rb +0 -40
  131. data/lib/tcell_agent/rust/libtcellagent-1.3.2.dylib +0 -0
  132. data/lib/tcell_agent/rust/tcellagent-1.3.2.dll +0 -0
  133. data/lib/tcell_agent/rust/whisperer.rb +0 -308
  134. data/lib/tcell_agent/sensor_events/appsensor_event.rb +0 -52
  135. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +0 -45
  136. data/lib/tcell_agent/sensor_events/command_injection.rb +0 -75
  137. data/lib/tcell_agent/sensor_events/honeytokens.rb +0 -16
  138. data/lib/tcell_agent/sensor_events/login_fraud.rb +0 -60
  139. data/lib/tcell_agent/sensor_events/metrics.rb +0 -123
  140. data/lib/tcell_agent/sensor_events/patches.rb +0 -21
  141. data/lib/tcell_agent/start_background_thread.rb +0 -55
  142. data/lib/tcell_agent/system_info.rb +0 -11
  143. data/lib/tcell_agent/utils/io.rb +0 -38
  144. data/lib/tcell_agent/utils/passwords.rb +0 -28
  145. data/lib/tcell_agent/utils/queue_with_timeout.rb +0 -142
  146. data/spec/lib/tcell_agent/agent/fork_pipe_manager_spec.rb +0 -100
  147. data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +0 -535
  148. data/spec/lib/tcell_agent/agent/static_agent_spec.rb +0 -133
  149. data/spec/lib/tcell_agent/api/api_spec.rb +0 -39
  150. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +0 -187
  151. data/spec/lib/tcell_agent/instrumentation_spec.rb +0 -225
  152. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +0 -517
  153. data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +0 -22
  154. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +0 -293
  155. data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +0 -198
  156. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +0 -180
  157. data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +0 -116
  158. data/spec/lib/tcell_agent/rust/models_spec.rb +0 -120
  159. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +0 -704
  160. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +0 -45
  161. data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +0 -272
  162. data/spec/lib/tcell_agent/utils/bounded_queue_spec.rb +0 -52
  163. data/spec/lib/tcell_agent/utils/passwords_spec.rb +0 -143
@@ -1,24 +0,0 @@
1
- require 'tcell_agent/sensor_events/appsensor_event'
2
-
3
- module TCellAgent
4
- module AppSensor
5
- module InjectionsReporter
6
- def self.report_and_log(events)
7
- (events || []).each do |event|
8
- TCellAgent.send_event(
9
- TCellAgent::SensorEvents::TCellAppSensorEvent.build_from_native_lib_event(event)
10
- )
11
-
12
- next unless event.key?('full_payload')
13
- event_to_log = {}.merge(event)
14
- event_to_log['payload'] = event_to_log.delete('full_payload')
15
-
16
- cleaned_event = TCellAgent::SensorEvents::TCellAppSensorEvent.build_from_native_lib_event(
17
- event_to_log
18
- )
19
- TCellAgent.logger.info(JSON.dump(cleaned_event))
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,8 +0,0 @@
1
- # Forces event manager to start in child processes
2
- # Conditionally loaded based on config
3
- class << TCellAgent::Agent
4
- alias_method :tcell_parent_process?, :parent_process?
5
- def parent_process?
6
- true
7
- end
8
- end
@@ -1,10 +0,0 @@
1
- module Kernel
2
- alias_method :tcell_original_backtick, :`
3
- def `(cmd)
4
- if TCellAgent::Cmdi.block_command?(cmd)
5
- raise Errno::ENOENT, "tCell.io Agent: Command not allowed by policy: #{cmd}"
6
- end
7
-
8
- tcell_original_backtick(cmd)
9
- end
10
- end
@@ -1,14 +0,0 @@
1
- module Kernel
2
- alias_method :tcell_original_exec, :exec
3
-
4
- private
5
-
6
- def exec(*args)
7
- cmd = TCellAgent::Cmdi.parse_command(*args)
8
- if TCellAgent::Cmdi.block_command?(cmd)
9
- raise Errno::ENOENT, "tCell.io Agent: Command not allowed by policy: #{cmd}"
10
- end
11
-
12
- tcell_original_exec(*args)
13
- end
14
- end
@@ -1,28 +0,0 @@
1
- class IO
2
- class << self
3
- alias_method :tcell_original_popen, :popen
4
- def popen(*args, &block)
5
- unless args.empty?
6
- cmd = ''
7
-
8
- TCellAgent::Instrumentation.safe_block('CMDI Parsing popen *args') do
9
- args_copy = Array.new(args)
10
- args_copy.shift if args_copy.first.is_a?(Hash)
11
- args_copy.pop if args_copy.last.is_a?(Hash)
12
-
13
- cmd = if args_copy.first.is_a?(String)
14
- args_copy.shift
15
- else
16
- TCellAgent::Cmdi.parse_command(*args_copy.shift)
17
- end
18
- end
19
-
20
- if TCellAgent::Cmdi.block_command?(cmd)
21
- raise Errno::ENOENT, "tCell.io Agent: Command not allowed by policy: #{cmd}"
22
- end
23
- end
24
-
25
- tcell_original_popen(*args, &block)
26
- end
27
- end
28
- end
@@ -1,11 +0,0 @@
1
- module Kernel
2
- alias_method :tcell_original_spawn, :spawn
3
- def spawn(*args)
4
- cmd = TCellAgent::Cmdi.parse_command(*args)
5
- if TCellAgent::Cmdi.block_command?(cmd)
6
- raise Errno::ENOENT, "tCell.io Agent: Command not allowed by policy: #{cmd}"
7
- end
8
-
9
- tcell_original_spawn(*args)
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- module Kernel
2
- alias_method :tcell_original_system, :system
3
- def system(*args)
4
- cmd = TCellAgent::Cmdi.parse_command(*args)
5
- if TCellAgent::Cmdi.block_command?(cmd)
6
- raise Errno::ENOENT, "tCell.io Agent: Command not allowed by policy: #{cmd}"
7
- end
8
-
9
- tcell_original_system(*args)
10
- end
11
- end
@@ -1,60 +0,0 @@
1
- # {}"http-tx": {
2
- # "policy_id":"afh023",
3
- # "types": {
4
- # "firehose": { enabled: true },
5
- # {}"auth_framework_only": {enabled: true},
6
- # {}"{}structure": {enabled: true },
7
- # {}"fingerprint": {enabled: true }
8
- # }
9
- # },
10
-
11
- require 'tcell_agent/policies/policy'
12
-
13
- module TCellAgent
14
- module Policies
15
- class HttpTxPolicy < Policy
16
- attr_accessor :policy_id, :firehose, :auth_framework, :profile, :fingerprint
17
-
18
- def initialize
19
- @firehose = { 'enabled' => false, 'lite' => false }
20
- @auth_framework = { 'enabled' => false, 'lite' => false }
21
- @profile = { 'enabled' => false }
22
- @fingerprint = { 'enabled' => false, 'hmacUserAgent' => false, 'hmacUserId' => false, 'sampling' => nil }
23
- end
24
-
25
- def self.from_json(policy_json)
26
- return nil unless policy_json
27
- http_tx_policy = HttpTxPolicy.new
28
-
29
- http_tx_policy.policy_id = policy_json['policy_id']
30
- raise 'Policy ID missing' unless http_tx_policy.policy_id
31
-
32
- types = policy_json['types']
33
- return http_tx_policy unless types
34
-
35
- if types.key?('firehose')
36
- http_tx_policy.firehose['enabled'] = types['firehose'].fetch('enabled', false)
37
- http_tx_policy.firehose['lite'] = types['firehose'].fetch('lite', false)
38
- end
39
-
40
- if types.key?('auth_framework')
41
- http_tx_policy.auth_framework['enabled'] = types['auth_framework'].fetch('enabled', false)
42
- http_tx_policy.auth_framework['lite'] = types['auth_framework'].fetch('lite', false)
43
- end
44
-
45
- if types.key?('profile')
46
- http_tx_policy.profile['enabled'] = types['profile'].fetch('enabled', false)
47
- end
48
-
49
- if types.key?('fingerprint')
50
- http_tx_policy.fingerprint['enabled'] = types['fingerprint'].fetch('enabled', false)
51
- http_tx_policy.fingerprint['hmacUserAgent'] = types['fingerprint'].fetch('hmacUserAgent', false)
52
- http_tx_policy.fingerprint['hmacUserId'] = types['fingerprint'].fetch('hmacUserId', false)
53
- http_tx_policy.fingerprint['sampling'] = types['fingerprint'].fetch('sampling', 0)
54
- end
55
-
56
- http_tx_policy
57
- end
58
- end
59
- end
60
- end
@@ -1,45 +0,0 @@
1
- require 'tcell_agent/policies/policy'
2
-
3
- module TCellAgent
4
- module Policies
5
- class LoginFraudPolicy < Policy
6
- attr_accessor :policy_id
7
-
8
- attr_accessor :login_success_enabled
9
- attr_accessor :login_failed_enabled
10
- attr_accessor :session_hijacking_metrics
11
-
12
- def initialize
13
- init_options
14
- end
15
-
16
- def init_options
17
- @policy_id = nil
18
- @login_success_enabled = false
19
- @login_failed_enabled = false
20
- @session_hijacking_metrics = false
21
- end
22
-
23
- def enabled
24
- @login_success_enabled || @login_failed_enabled
25
- end
26
-
27
- def self.from_json(policy_json)
28
- return nil unless policy_json
29
- sensor_policy = LoginFraudPolicy.new
30
-
31
- sensor_policy.policy_id = policy_json['policy_id']
32
- raise 'Policy ID missing' unless sensor_policy.policy_id
33
-
34
- options_json = (policy_json['data'] || {})['options']
35
- return sensor_policy unless options_json
36
-
37
- sensor_policy.login_failed_enabled = options_json.fetch('login_failed_enabled', false)
38
- sensor_policy.login_success_enabled = options_json.fetch('login_success_enabled', false)
39
- sensor_policy.session_hijacking_metrics = options_json.fetch('session_hijacking_enabled', false)
40
-
41
- sensor_policy
42
- end
43
- end
44
- end
45
- end
@@ -1,110 +0,0 @@
1
- require 'tcell_agent/appsensor/injections_reporter'
2
- require 'tcell_agent/instrumentation'
3
- require 'tcell_agent/policies/policy'
4
- require 'tcell_agent/rust/models'
5
- require 'tcell_agent/rust/whisperer'
6
- require 'tcell_agent/sensor_events/command_injection'
7
- require 'tcell_agent/sensor_events/patches'
8
-
9
- module TCellAgent
10
- module Policies
11
- class RustPolicies < Policy
12
- attr_reader :appfirewall_enabled, :patches_enabled, :cmdi_enabled
13
-
14
- def initialize
15
- @appfirewall_enabled = false
16
- @patches_enabled = false
17
- @cmdi_enabled = false
18
- @headers_enabled = false
19
- @jsagent_enabled = false
20
- @agent_ptr = nil
21
-
22
- whisper = TCellAgent::Rust::Whisperer.create_agent
23
- if whisper['error']
24
- TCellAgent.logger.error("Error initializing policies: #{whisper['error']}")
25
- else
26
- @agent_ptr = whisper['agent_ptr']
27
- end
28
- end
29
-
30
- def update_policies(policies_json)
31
- return if @agent_ptr.nil? || policies_json.nil? || policies_json.empty?
32
-
33
- whisper = TCellAgent::Rust::Whisperer.update_policies(@agent_ptr, policies_json)
34
- if whisper['errors']
35
- whisper['errors'].each do |error|
36
- TCellAgent.logger.error("Error updating policies: #{error}")
37
- end
38
- else
39
- enablements = whisper['enablements']
40
- @appfirewall_enabled = enablements['appfirewall']
41
- @patches_enabled = enablements['patches']
42
- @cmdi_enabled = enablements['cmdi']
43
- @headers_enabled = enablements['headers']
44
- @jsagent_enabled = enablements['jsagentinjection']
45
- end
46
- end
47
-
48
- def block_request?(appsensor_meta)
49
- return false unless @agent_ptr && @patches_enabled
50
-
51
- whisper = TCellAgent::Rust::Whisperer.apply_patches(@agent_ptr, appsensor_meta)
52
- if whisper['error']
53
- TCellAgent.logger.error("Error processing patches: #{whisper['error']}")
54
- else
55
- response = whisper['apply_response']
56
- if response && response['status'] == 'Blocked'
57
- patches_event = TCellAgent::SensorEvents::PatchesEvent.new(response, appsensor_meta)
58
- TCellAgent.send_event(patches_event)
59
- return true
60
- end
61
- end
62
-
63
- false
64
- end
65
-
66
- def check_appfirewall_injections(appsensor_meta)
67
- return unless @agent_ptr && @appfirewall_enabled
68
-
69
- TCellAgent::Instrumentation.safe_block('AppSensor inspection') do
70
- whisper = TCellAgent::Rust::Whisperer.apply_appfirewall(@agent_ptr, appsensor_meta)
71
- TCellAgent::AppSensor::InjectionsReporter.report_and_log(whisper['apply_response'])
72
- end
73
- end
74
-
75
- def block_command?(command, tcell_context)
76
- return false unless @agent_ptr &&
77
- @cmdi_enabled &&
78
- TCellAgent.safe_to_send_cmdi_events?
79
- whisper = TCellAgent::Rust::Whisperer.apply_cmdi(
80
- @agent_ptr, command, tcell_context
81
- )
82
- apply_response = whisper.fetch('apply_response', {})
83
- cmdi_event =
84
- TCellAgent::SensorEvents::CommandInjectionEvent.build_from_native_lib_response_and_tcell_context(apply_response,
85
- tcell_context)
86
- TCellAgent.send_event(cmdi_event) if cmdi_event
87
-
88
- apply_response.fetch('blocked', false)
89
- end
90
-
91
- def get_headers(tcell_context)
92
- return [] unless @agent_ptr &&
93
- @headers_enabled
94
- whisper = TCellAgent::Rust::Whisperer.get_headers(
95
- @agent_ptr, tcell_context
96
- )
97
- whisper['headers'] || []
98
- end
99
-
100
- def get_js_agent_script_tag(tcell_context)
101
- return nil unless @agent_ptr &&
102
- @jsagent_enabled
103
- whisper = TCellAgent::Rust::Whisperer.get_js_agent_script_tag(
104
- @agent_ptr, tcell_context
105
- )
106
- whisper['script_tag']
107
- end
108
- end
109
- end
110
- end
@@ -1,40 +0,0 @@
1
- # See the file "LICENSE" for the full license governing this code.
2
-
3
- require 'rails'
4
- require 'uri'
5
- require 'tcell_agent/agent'
6
- require 'tcell_agent/sensor_events/sensor'
7
- require 'tcell_agent/sensor_events/server_agent'
8
- require 'tcell_agent/sensor_events/util/sanitizer_utilities'
9
-
10
- require 'tcell_agent/rails/better_ip'
11
- require 'tcell_agent/rails/middleware/global_middleware'
12
- require 'tcell_agent/rails/middleware/body_filter_middleware'
13
- require 'tcell_agent/rails/middleware/headers_middleware'
14
- require 'tcell_agent/rails/middleware/context_middleware'
15
-
16
- require 'tcell_agent/rails/settings_reporter'
17
- require 'tcell_agent/rails/dlp'
18
- require 'tcell_agent/rails/csrf_exception'
19
-
20
- require 'tcell_agent/userinfo'
21
- require 'cgi'
22
- require 'thread'
23
-
24
- module TCellAgent
25
- class Railtie < Rails::Railtie
26
- initializer 'tcell_agent.insert_middleware' do |app|
27
- app.config.to_prepare do
28
- require 'tcell_agent/devise' if defined?(Devise)
29
- require 'tcell_agent/rails/auth/devise' if defined?(Devise)
30
- require 'tcell_agent/authlogic' if defined?(Authlogic)
31
- require 'tcell_agent/rails/auth/authlogic' if defined?(Authlogic)
32
- require 'tcell_agent/rails/auth/doorkeeper'
33
- end
34
- app.config.middleware.insert_before(0, TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware)
35
- app.config.middleware.insert_after(0, TCellAgent::Instrumentation::Rails::Middleware::HeadersMiddleware)
36
- app.config.middleware.use TCellAgent::Instrumentation::Rails::Middleware::BodyFilterMiddleware
37
- app.config.middleware.use TCellAgent::Instrumentation::Rails::Middleware::GlobalMiddleware
38
- end
39
- end
40
- end
@@ -1,308 +0,0 @@
1
- require 'tcell_agent/rust/models'
2
- require 'tcell_agent/logger'
3
-
4
- module TCellAgent
5
- module Rust
6
- require 'ffi'
7
-
8
- module Wrapper
9
- extend FFI::Library
10
-
11
- VERSION = '1.3.2'.freeze
12
- prefix = 'lib'
13
- extension = '.so'
14
- variant = ''
15
- if /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
16
- extension = '.dll'
17
- prefix = ''
18
- elsif /darwin/ =~ RUBY_PLATFORM
19
- extension = '.dylib'
20
- elsif /musl/ =~ RUBY_PLATFORM
21
- variant = 'alpine-'
22
- end
23
-
24
- begin
25
- ffi_lib File.join(File.dirname(__FILE__),
26
- "#{prefix}tcellagent-#{variant}#{VERSION}#{extension}")
27
-
28
- # All the rust library calls have the following response api:
29
- #
30
- # result [int]: 0+ length of buffer_out answer
31
- # -1 general error
32
- # -2 buffer_out is not big enough for response
33
- # -3 buffer_out is null
34
-
35
- attach_function :create_agent, %i[pointer size_t pointer size_t], :int
36
- attach_function :free_agent, [:pointer], :int
37
- attach_function :update_policies, %i[pointer pointer size_t pointer size_t], :int
38
- attach_function :appfirewall_apply, %i[pointer pointer size_t pointer size_t], :int
39
- attach_function :patches_apply, %i[pointer pointer size_t pointer size_t], :int
40
- attach_function :cmdi_apply, %i[pointer pointer size_t pointer size_t], :int
41
- attach_function :get_headers, %i[pointer pointer size_t pointer size_t], :int
42
- attach_function :get_js_agent_script_tag, %i[pointer pointer size_t pointer size_t], :int
43
-
44
- def self.common_lib_available?
45
- true
46
- end
47
- rescue LoadError => load_error
48
- puts "tCell.io Failed to load common agent library. #{load_error.message}"
49
- TCellAgent.logger.error("Failed to load common agent library. #{load_error.message}")
50
- TCellAgent.logger.debug(load_error.backtrace)
51
-
52
- def self.common_lib_available? # rubocop:disable Lint/DuplicateMethods
53
- false
54
- end
55
- end
56
- end
57
-
58
- module Whisperer
59
- def self.convert_result(function_called, result_size, result)
60
- if result_size < 0
61
- TCellAgent.logger.error(
62
- "Error response from `#{function_called}` in native library: #{result_size}"
63
- )
64
- else
65
- begin
66
- response = JSON.parse(result.get_string(0, result_size))
67
- if response['error']
68
- TCellAgent.logger.error("#{function_called} returned an error: #{response['error']}")
69
- response = {}
70
- end
71
-
72
- return response
73
- rescue JSON::ParserError
74
- # don't log the actual error since it might contain payload information
75
- TCellAgent.logger.error(
76
- "Could not parse json response from `#{function_called}` in native library."
77
- )
78
- end
79
- end
80
-
81
- {}
82
- end
83
-
84
- def self.create_agent
85
- if TCellAgent::Rust::Wrapper.common_lib_available?
86
- agent_config = {
87
- 'skip_logger' => true,
88
- 'application' => {
89
- 'app_id' => TCellAgent.configuration.app_id,
90
- 'api_key' => TCellAgent.configuration.api_key,
91
- 'allow_payloads' => !!TCellAgent.configuration.allow_payloads, # rubocop:disable Style/DoubleNegation
92
- 'js_agent_api_base_url' => TCellAgent.configuration.js_agent_api_base_url,
93
- 'js_agent_url' => TCellAgent.configuration.js_agent_url
94
- },
95
- 'appfirewall' => {
96
- 'enable_body_xxe_inspection' => true,
97
- 'enable_body_json_inspection' => true,
98
- 'allow_log_payloads' => true
99
- },
100
- 'policy_versions' => {
101
- 'patches' => 1,
102
- 'login' => 1,
103
- 'appsensor' => 2,
104
- 'regex' => 1,
105
- 'csp-headers' => 1,
106
- 'http-redirect' => 1,
107
- 'clickjacking' => 1,
108
- 'secure-headers' => 1,
109
- 'canaries' => 1,
110
- 'dlp' => 1,
111
- 'cmdi' => 1,
112
- 'jsagentinjection' => 1
113
- },
114
- 'max_header_size' => TCellAgent.configuration.max_csp_header_bytes || (1024 * 1024)
115
- }
116
- config_pointer = FFI::MemoryPointer.from_string(
117
- JSON.dump(agent_config)
118
- )
119
-
120
- buf = FFI::MemoryPointer.new(:uint8, 1024 * 8)
121
- # config_pointer.size - 1: strips null terminator
122
- result_size = TCellAgent::Rust::Wrapper.create_agent(
123
- config_pointer, config_pointer.size - 1, buf, buf.size
124
- )
125
- return convert_result('create_agent', result_size, buf)
126
- end
127
-
128
- {}
129
- end
130
-
131
- def self.free_agent(agent_ptr)
132
- if TCellAgent::Rust::Wrapper.common_lib_available? &&
133
- agent_ptr
134
- TCellAgent::Rust::Wrapper.free_agent(
135
- FFI::Pointer.new(agent_ptr)
136
- )
137
- end
138
- end
139
-
140
- def self.update_policies(agent_ptr, policies)
141
- if TCellAgent::Rust::Wrapper.common_lib_available? &&
142
- agent_ptr &&
143
- TCellAgent::Utils::Strings.present?(policies)
144
- policies_pointer = FFI::MemoryPointer.from_string(
145
- JSON.dump(policies)
146
- )
147
-
148
- buf = FFI::MemoryPointer.new(:uint8, 1024 * 8)
149
- # policies_pointer.size - 1: strips null terminator
150
- result_size = TCellAgent::Rust::Wrapper.update_policies(
151
- FFI::Pointer.new(agent_ptr),
152
- policies_pointer,
153
- policies_pointer.size - 1,
154
- buf,
155
- buf.size
156
- )
157
- return convert_result('update_policies', result_size, buf)
158
- end
159
-
160
- {}
161
- end
162
-
163
- def self.apply_appfirewall(agent_ptr, appsensor_meta)
164
- if TCellAgent::Rust::Wrapper.common_lib_available? &&
165
- agent_ptr &&
166
- appsensor_meta
167
- request_response_json = TCellAgent::Rust::Models.create_request_response(
168
- appsensor_meta
169
- )
170
- request_response_pointer = FFI::MemoryPointer.from_string(
171
- JSON.dump(request_response_json)
172
- )
173
-
174
- buf = FFI::MemoryPointer.new(:uint8, 1024 * 32)
175
- # request_response_pointer.size - 1: strips null terminator
176
- result_size = TCellAgent::Rust::Wrapper.appfirewall_apply(
177
- FFI::Pointer.new(agent_ptr),
178
- request_response_pointer,
179
- request_response_pointer.size - 1,
180
- buf,
181
- buf.size
182
- )
183
- return convert_result('apply_appfirewall', result_size, buf)
184
- end
185
-
186
- {}
187
- end
188
-
189
- def self.apply_patches(agent_ptr, appsensor_meta)
190
- if TCellAgent::Rust::Wrapper.common_lib_available? &&
191
- agent_ptr &&
192
- appsensor_meta
193
- patches_request_json = TCellAgent::Rust::Models.create_patches_request(
194
- appsensor_meta
195
- )
196
- patches_request_pointer = FFI::MemoryPointer.from_string(
197
- JSON.dump(patches_request_json)
198
- )
199
-
200
- buf = FFI::MemoryPointer.new(:uint8, 1024 * 32)
201
- # patches_request_pointer.size - 1: strips null terminator
202
- result_size = TCellAgent::Rust::Wrapper.patches_apply(
203
- FFI::Pointer.new(agent_ptr),
204
- patches_request_pointer,
205
- patches_request_pointer.size - 1,
206
- buf,
207
- buf.size
208
- )
209
- return convert_result('apply_patches', result_size, buf)
210
- end
211
-
212
- {}
213
- end
214
-
215
- def self.apply_cmdi(agent_ptr, command, tcell_context)
216
- if TCellAgent::Rust::Wrapper.common_lib_available? &&
217
- agent_ptr &&
218
- TCellAgent::Utils::Strings.present?(command)
219
- method = tcell_context && tcell_context.request_method
220
- path = tcell_context && tcell_context.path
221
- command_info = {
222
- 'command' => command,
223
- 'method' => method,
224
- 'path' => path
225
- }
226
- command_pointer = FFI::MemoryPointer.from_string(
227
- JSON.dump(command_info)
228
- )
229
-
230
- buf = FFI::MemoryPointer.new(:uint8, 1024 * 32)
231
- # patches_request_pointer.size - 1: strips null terminator
232
- result_size = TCellAgent::Rust::Wrapper.cmdi_apply(
233
- FFI::Pointer.new(agent_ptr),
234
- command_pointer,
235
- command_pointer.size - 1,
236
- buf,
237
- buf.size
238
- )
239
- return convert_result('apply_cmdi', result_size, buf)
240
- end
241
-
242
- {}
243
- end
244
-
245
- def self.get_headers(agent_ptr, tcell_context)
246
- if TCellAgent::Rust::Wrapper.common_lib_available? &&
247
- agent_ptr &&
248
- tcell_context
249
- method = tcell_context.request_method
250
- path = tcell_context.path
251
- route_id = tcell_context.route_id
252
- session_id = tcell_context.hmac_session_id
253
- headers_request = {
254
- :method => method,
255
- :path => path,
256
- :route_id => route_id && route_id.to_s,
257
- :session_id => session_id && session_id.to_s
258
- }
259
- headers_request_pointer = FFI::MemoryPointer.from_string(
260
- JSON.dump(headers_request)
261
- )
262
-
263
- buf = FFI::MemoryPointer.new(:uint8, 1024 * 16)
264
- # patches_request_pointer.size - 1: strips null terminator
265
- result_size = TCellAgent::Rust::Wrapper.get_headers(
266
- FFI::Pointer.new(agent_ptr),
267
- headers_request_pointer,
268
- headers_request_pointer.size - 1,
269
- buf,
270
- buf.size
271
- )
272
- return convert_result('get_headers', result_size, buf)
273
- end
274
-
275
- {}
276
- end
277
-
278
- def self.get_js_agent_script_tag(agent_ptr, tcell_context)
279
- if TCellAgent::Rust::Wrapper.common_lib_available? &&
280
- agent_ptr &&
281
- tcell_context
282
- method = tcell_context.request_method
283
- path = tcell_context.path
284
- jsagent_request = {
285
- :method => method,
286
- :path => path
287
- }
288
- jsagent_request_pointer = FFI::MemoryPointer.from_string(
289
- JSON.dump(jsagent_request)
290
- )
291
-
292
- buf = FFI::MemoryPointer.new(:uint8, 1024 * 8)
293
- # patches_request_pointer.size - 1: strips null terminator
294
- result_size = TCellAgent::Rust::Wrapper.get_js_agent_script_tag(
295
- FFI::Pointer.new(agent_ptr),
296
- jsagent_request_pointer,
297
- jsagent_request_pointer.size - 1,
298
- buf,
299
- buf.size
300
- )
301
- return convert_result('get_js_agent_script_tag', result_size, buf)
302
- end
303
-
304
- {}
305
- end
306
- end
307
- end
308
- end