tcell_agent 1.1.12 → 2.2.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 (169) hide show
  1. checksums.yaml +5 -5
  2. data/bin/tcell_agent +45 -137
  3. data/lib/tcell_agent.rb +12 -14
  4. data/lib/tcell_agent/agent.rb +108 -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/config_initializer.rb +66 -0
  8. data/lib/tcell_agent/configuration.rb +69 -345
  9. data/lib/tcell_agent/hooks/login_fraud.rb +30 -33
  10. data/lib/tcell_agent/instrument_servers.rb +23 -0
  11. data/lib/tcell_agent/instrumentation.rb +12 -10
  12. data/lib/tcell_agent/instrumentation/cmdi.rb +29 -25
  13. data/lib/tcell_agent/instrumentation/lfi.rb +84 -0
  14. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +25 -0
  15. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +131 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +102 -0
  17. data/lib/tcell_agent/logger.rb +49 -114
  18. data/lib/tcell_agent/patches.rb +6 -7
  19. data/lib/tcell_agent/policies/appfirewall_policy.rb +26 -0
  20. data/lib/tcell_agent/policies/command_injection_policy.rb +28 -0
  21. data/lib/tcell_agent/policies/dataloss_policy.rb +44 -44
  22. data/lib/tcell_agent/policies/headers_policy.rb +25 -0
  23. data/lib/tcell_agent/policies/http_redirect_policy.rb +13 -79
  24. data/lib/tcell_agent/policies/js_agent_policy.rb +27 -0
  25. data/lib/tcell_agent/policies/local_file_access.rb +28 -0
  26. data/lib/tcell_agent/policies/login_policy.rb +43 -0
  27. data/lib/tcell_agent/policies/patches_policy.rb +27 -0
  28. data/lib/tcell_agent/policies/policies_manager.rb +68 -0
  29. data/lib/tcell_agent/policies/policy_polling.rb +58 -0
  30. data/lib/tcell_agent/policies/policy_types.rb +14 -0
  31. data/lib/tcell_agent/policies/system_enablements.rb +27 -0
  32. data/lib/tcell_agent/rails/auth/authlogic.rb +46 -75
  33. data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
  34. data/lib/tcell_agent/rails/auth/devise.rb +100 -105
  35. data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
  36. data/lib/tcell_agent/rails/auth/doorkeeper.rb +62 -76
  37. data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
  38. data/lib/tcell_agent/rails/csrf_exception.rb +2 -10
  39. data/lib/tcell_agent/rails/dlp.rb +35 -23
  40. data/lib/tcell_agent/rails/dlp_handler.rb +1 -2
  41. data/lib/tcell_agent/rails/js_agent_insert.rb +12 -13
  42. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +4 -25
  43. data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -12
  44. data/lib/tcell_agent/rails/middleware/global_middleware.rb +1 -2
  45. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +14 -34
  46. data/lib/tcell_agent/{rails.rb → rails/railties/tcell_agent_railties.rb} +11 -16
  47. data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
  48. data/lib/tcell_agent/rails/routes.rb +10 -12
  49. data/lib/tcell_agent/rails/routes/grape.rb +4 -14
  50. data/lib/tcell_agent/rails/routes/route_id.rb +3 -1
  51. data/lib/tcell_agent/rails/settings_reporter.rb +23 -36
  52. data/lib/tcell_agent/rails/tcell_body_proxy.rb +5 -4
  53. data/lib/tcell_agent/rust/agent_config.rb +60 -0
  54. data/lib/tcell_agent/rust/{libtcellagent-alpine-1.3.2.so → libtcellagent-5.0.2.dylib} +0 -0
  55. data/lib/tcell_agent/rust/{libtcellagent-1.3.2.so → libtcellagent-5.0.2.so} +0 -0
  56. data/lib/tcell_agent/rust/libtcellagent-alpine-5.0.2.so +0 -0
  57. data/lib/tcell_agent/rust/models.rb +6 -52
  58. data/lib/tcell_agent/rust/native_agent.rb +549 -0
  59. data/lib/tcell_agent/rust/native_agent_response.rb +42 -0
  60. data/lib/tcell_agent/rust/native_library.rb +69 -0
  61. data/lib/tcell_agent/rust/tcellagent-5.0.2.dll +0 -0
  62. data/lib/tcell_agent/sensor_events/agent_setting_event.rb +12 -0
  63. data/lib/tcell_agent/sensor_events/{app_config.rb → app_config_setting_event.rb} +0 -6
  64. data/lib/tcell_agent/sensor_events/dlp.rb +2 -6
  65. data/lib/tcell_agent/sensor_events/sensor.rb +0 -62
  66. data/lib/tcell_agent/sensor_events/server_agent.rb +13 -18
  67. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +0 -108
  68. data/lib/tcell_agent/sensor_events/util/utils.rb +0 -2
  69. data/lib/tcell_agent/servers/passenger.rb +1 -28
  70. data/lib/tcell_agent/servers/puma.rb +3 -21
  71. data/lib/tcell_agent/servers/rails_server.rb +1 -2
  72. data/lib/tcell_agent/servers/thin.rb +2 -2
  73. data/lib/tcell_agent/servers/unicorn.rb +19 -80
  74. data/lib/tcell_agent/servers/webrick.rb +1 -2
  75. data/lib/tcell_agent/settings_reporter.rb +11 -90
  76. data/lib/tcell_agent/sinatra.rb +14 -16
  77. data/lib/tcell_agent/tcell_context.rb +40 -14
  78. data/lib/tcell_agent/utils/headers.rb +14 -0
  79. data/lib/tcell_agent/version.rb +1 -1
  80. data/spec/lib/tcell_agent/configuration_spec.rb +55 -346
  81. data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +46 -173
  82. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +504 -0
  83. data/spec/lib/tcell_agent/instrumentation/cmdi/kernel_cmdi_spec.rb +435 -0
  84. data/spec/lib/tcell_agent/instrumentation/cmdi_spec.rb +201 -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 +562 -0
  87. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +264 -0
  88. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +150 -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/rust/agent_config_spec.rb +27 -0
  108. data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +0 -35
  109. data/spec/lib/tcell_agent/settings_reporter_spec.rb +56 -155
  110. data/spec/spec_helper.rb +1 -1
  111. data/spec/support/builders.rb +103 -0
  112. data/spec/support/force_logger_mocking.rb +38 -0
  113. data/spec/support/resources/lfi_sample_file.txt +2 -0
  114. data/spec/support/static_agent_overrides.rb +0 -15
  115. metadata +72 -83
  116. data/lib/tcell_agent/agent/event_processor.rb +0 -326
  117. data/lib/tcell_agent/agent/fork_pipe_manager.rb +0 -113
  118. data/lib/tcell_agent/agent/policy_manager.rb +0 -219
  119. data/lib/tcell_agent/agent/policy_types.rb +0 -30
  120. data/lib/tcell_agent/api.rb +0 -91
  121. data/lib/tcell_agent/appsensor/injections_reporter.rb +0 -24
  122. data/lib/tcell_agent/authlogic.rb +0 -26
  123. data/lib/tcell_agent/config/child_process_events.rb +0 -8
  124. data/lib/tcell_agent/config/unknown_options.rb +0 -123
  125. data/lib/tcell_agent/devise.rb +0 -35
  126. data/lib/tcell_agent/instrumentation/cmdi/backtick.rb +0 -10
  127. data/lib/tcell_agent/instrumentation/cmdi/exec.rb +0 -14
  128. data/lib/tcell_agent/instrumentation/cmdi/popen.rb +0 -28
  129. data/lib/tcell_agent/instrumentation/cmdi/spawn.rb +0 -11
  130. data/lib/tcell_agent/instrumentation/cmdi/system.rb +0 -11
  131. data/lib/tcell_agent/policies/http_tx_policy.rb +0 -60
  132. data/lib/tcell_agent/policies/login_fraud_policy.rb +0 -45
  133. data/lib/tcell_agent/policies/rust_policies.rb +0 -110
  134. data/lib/tcell_agent/rails/on_start.rb +0 -41
  135. data/lib/tcell_agent/rust/libtcellagent-1.3.2.dylib +0 -0
  136. data/lib/tcell_agent/rust/tcellagent-1.3.2.dll +0 -0
  137. data/lib/tcell_agent/rust/whisperer.rb +0 -308
  138. data/lib/tcell_agent/sensor_events/appsensor_event.rb +0 -52
  139. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +0 -45
  140. data/lib/tcell_agent/sensor_events/command_injection.rb +0 -75
  141. data/lib/tcell_agent/sensor_events/honeytokens.rb +0 -16
  142. data/lib/tcell_agent/sensor_events/login_fraud.rb +0 -60
  143. data/lib/tcell_agent/sensor_events/metrics.rb +0 -123
  144. data/lib/tcell_agent/sensor_events/patches.rb +0 -21
  145. data/lib/tcell_agent/start_background_thread.rb +0 -55
  146. data/lib/tcell_agent/system_info.rb +0 -11
  147. data/lib/tcell_agent/utils/io.rb +0 -38
  148. data/lib/tcell_agent/utils/passwords.rb +0 -28
  149. data/lib/tcell_agent/utils/queue_with_timeout.rb +0 -142
  150. data/spec/lib/tcell_agent/agent/fork_pipe_manager_spec.rb +0 -100
  151. data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +0 -535
  152. data/spec/lib/tcell_agent/agent/static_agent_spec.rb +0 -133
  153. data/spec/lib/tcell_agent/api/api_spec.rb +0 -39
  154. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +0 -187
  155. data/spec/lib/tcell_agent/cmdi_spec.rb +0 -736
  156. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -213
  157. data/spec/lib/tcell_agent/instrumentation_spec.rb +0 -225
  158. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +0 -517
  159. data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +0 -22
  160. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +0 -293
  161. data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +0 -198
  162. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +0 -180
  163. data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +0 -116
  164. data/spec/lib/tcell_agent/rust/models_spec.rb +0 -120
  165. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +0 -704
  166. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +0 -45
  167. data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +0 -272
  168. data/spec/lib/tcell_agent/utils/bounded_queue_spec.rb +0 -52
  169. data/spec/lib/tcell_agent/utils/passwords_spec.rb +0 -143
@@ -0,0 +1,102 @@
1
+ module Kernel
2
+ private
3
+
4
+ alias_method :tcell_original_backtick, :`
5
+ alias_method :tcell_original_exec, :exec
6
+ alias_method :tcell_original_open, :open
7
+ alias_method :tcell_original_gets, :gets
8
+ alias_method :tcell_original_readline, :readline
9
+ alias_method :tcell_original_spawn, :spawn
10
+ alias_method :tcell_original_system, :system
11
+
12
+ class << self
13
+ alias_method :tcell_original_exec, :exec
14
+ alias_method :tcell_original_open, :open
15
+ alias_method :tcell_original_gets, :gets
16
+ alias_method :tcell_original_readline, :readline
17
+ alias_method :tcell_original_spawn, :spawn
18
+ alias_method :tcell_original_system, :system
19
+ end
20
+
21
+ def `(cmd)
22
+ if TCellAgent::Cmdi.block_command?(cmd)
23
+ raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
24
+ end
25
+
26
+ tcell_original_backtick(cmd)
27
+ end
28
+
29
+ if TCellAgent.configuration.should_instrument?('kernel_exec')
30
+ def exec(*args)
31
+ cmd = TCellAgent::Cmdi.parse_command(*args)
32
+ if TCellAgent::Cmdi.block_command?(cmd)
33
+ raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
34
+ end
35
+
36
+ tcell_original_exec(*args)
37
+ end
38
+ end
39
+
40
+ def gets(*args, &block)
41
+ path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode_argf
42
+
43
+ if TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
44
+ raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
45
+ end
46
+
47
+ tcell_original_gets(*args, &block)
48
+ end
49
+
50
+ def open(*args, &block)
51
+ path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
52
+
53
+ if !path.strip.empty? && TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
54
+ raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
55
+ end
56
+
57
+ if path.empty?
58
+ cmd = TCellAgent::Cmdi.parse_command_from_open(*args)
59
+ if cmd && TCellAgent::Cmdi.block_command?(cmd)
60
+ raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
61
+ end
62
+ end
63
+
64
+ tcell_original_open(*args, &block)
65
+ end
66
+
67
+ def readline(*args, &block)
68
+ path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode_argf
69
+
70
+ if TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
71
+ raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
72
+ end
73
+
74
+ tcell_original_readline(*args, &block)
75
+ end
76
+
77
+ def spawn(*args)
78
+ cmd = TCellAgent::Cmdi.parse_command(*args)
79
+ if TCellAgent::Cmdi.block_command?(cmd)
80
+ raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
81
+ end
82
+
83
+ tcell_original_spawn(*args)
84
+ end
85
+
86
+ def system(*args)
87
+ cmd = TCellAgent::Cmdi.parse_command(*args)
88
+ if TCellAgent::Cmdi.block_command?(cmd)
89
+ raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
90
+ end
91
+
92
+ tcell_original_system(*args)
93
+ end
94
+
95
+ module_function :`
96
+ module_function :exec
97
+ module_function :gets
98
+ module_function :open
99
+ module_function :readline
100
+ module_function :spawn
101
+ module_function :system
102
+ end
@@ -2,149 +2,84 @@
2
2
 
3
3
  require 'logger'
4
4
  require 'tcell_agent/configuration'
5
- require 'tcell_agent/utils/io'
6
5
 
7
6
  module TCellAgent
8
- class TaggedLogger
9
- def initialize(tag, logger)
10
- @tag = tag
11
- @logger = logger
12
- end
13
-
14
- def debug(msg)
15
- @logger.tagged(@tag) { @logger.debug(msg) }
16
- end
17
-
18
- def info(msg)
19
- @logger.tagged(@tag) { @logger.info(msg) }
20
- end
21
-
22
- def warn(msg)
23
- @logger.tagged(@tag) { @logger.warn(msg) }
24
- end
25
-
26
- def error(msg)
27
- @logger.tagged(@tag) { @logger.error(msg) }
28
- end
29
-
30
- def fatal(msg)
31
- @logger.tagged(@tag) { @logger.fatal(msg) }
32
- end
33
-
34
- def unknown(msg)
35
- @logger.tagged(@tag) { @logger.unknown(msg) }
36
- end
37
- end
38
-
39
7
  class NullLoger < Logger
40
8
  def initialize(*args); end
41
9
 
42
10
  def add(*args, &block); end
43
11
  end
44
12
 
45
- class TCellLogDevice < Logger::LogDevice
46
- def create_logfile(filename)
47
- logdev = super
48
-
49
- TCellAgent::Utils::IO.set_owner(filename, TCellAgent.configuration.agent_home_owner.to_s)
13
+ class ModuleLogger
14
+ def initialize(logger, module_name)
15
+ @logger = logger
16
+ @module_name = module_name
17
+ end
50
18
 
51
- logdev
19
+ %i[exception debug info warn error].each do |method_name|
20
+ define_method(method_name) do |msg|
21
+ @logger.send(method_name, @module_name, msg)
22
+ end
52
23
  end
53
24
  end
54
25
 
55
- @@logger_pid = Process.pid
56
- @null_logger = TCellAgent::NullLoger.new
57
-
58
- def self.logging_level_from_string(level_string)
59
- return Logger::DEBUG if level_string == 'DEBUG'
60
- return Logger::WARN if level_string == 'WARN'
61
- return Logger::INFO if level_string == 'INFO'
62
- return Logger::ERROR if level_string == 'ERROR'
63
- return Logger::FATAL if level_string == 'FATAL'
64
-
65
- Logger::INFO
26
+ module ModuleLoggerAccess
27
+ def module_logger
28
+ @module_logger ||= ModuleLogger.new(
29
+ TCellAgent.logger, self.class.name
30
+ )
31
+ end
66
32
  end
67
33
 
68
- def self.appfirewall_payloads_logger
69
- return @null_logger unless TCellAgent.configuration.enabled
70
-
71
- if defined?(@paylods_logger) && @logger_pid == Process.pid
72
- return @payloads_logger
34
+ # Note: since the agent waits until native agent
35
+ # is available, this is only used in errors
36
+ # throwned while the agent is instrumenting or starting up
37
+ # so it's ok to send those to STDOUT always
38
+ class RubyLogger
39
+ def initialize
40
+ @logger = Logger.new(STDOUT)
73
41
  end
74
42
 
75
- if TCellAgent.configuration.appfirewall_payloads_logger
76
- @logger_pid = Process.pid
77
- @payloads_logger = TCellAgent.configuration.appfirewall_payloads_logger
78
- return @payloads_logger
43
+ def exception(module_name, exception)
44
+ @logger.debug("#{module_name} #{exception.backtrace.join("\n")}")
79
45
  end
80
46
 
81
- TCellAgent::Utils::IO.create_directory(
82
- File.dirname(TCellAgent.configuration.appfirewall_payloads_log_filename),
83
- TCellAgent.configuration.agent_home_owner.to_s
84
- )
85
-
86
- log_device = TCellLogDevice.new(
87
- TCellAgent.configuration.appfirewall_payloads_log_filename,
88
- :shift_age => 9, :shift_size => 5_242_880
89
- )
90
- @payloads_logger = Logger.new(log_device)
91
- @payloads_logger.level = Logger::INFO
92
- @payloads_logger.formatter = proc do |_severity, datetime, _progname, msg|
93
- date_format = datetime.strftime('%Y-%m-%dT%H:%M:%S.%L%:z')
94
- "#{date_format} - #{msg}\n"
47
+ %i[debug info warn error].each do |method_name|
48
+ define_method(method_name) do |module_name, msg|
49
+ @logger.send(method_name, "#{module_name} #{msg}")
50
+ end
95
51
  end
96
-
97
- @payloads_logger
98
52
  end
99
53
 
100
- def self.logger
101
- return @null_logger unless TCellAgent.configuration.enabled
102
-
103
- return @logger if defined?(@logger) && @logger_pid == Process.pid
104
-
105
- if TCellAgent.configuration.logger
106
- @logger_pid = Process.pid
107
- @logger = if TCellAgent.configuration.log_tag
108
- TCellAgent::TaggedLogger.new(TCellAgent.configuration.log_tag, TCellAgent.configuration.logger)
109
- else
110
- TCellAgent.configuration.logger
111
- end
112
-
113
- return @logger
54
+ class NativeLogger
55
+ def initialize(native_agent)
56
+ @native_agent = native_agent
114
57
  end
115
58
 
116
- @logger_pid = Process.pid
117
- logging_options = TCellAgent.configuration.logging_options || {}
118
-
119
- use_default_setting = !logging_options.key?(:enabled) && !logging_options.key?('enabled')
120
-
121
- if use_default_setting || logging_options[:enabled] || logging_options['enabled']
122
- logging_file = TCellAgent.configuration.log_filename
123
- logging_directory = File.dirname(logging_file)
124
- TCellAgent::Utils::IO.create_directory(logging_directory, TCellAgent.configuration.agent_home_owner.to_s)
125
-
126
- log_device = TCellLogDevice.new(logging_file, :shift_age => 9, :shift_size => 5_242_880)
59
+ def exception(module_name, exception)
60
+ @native_agent.log_message(
61
+ 'debug', exception.backtrace.join("\n"), module_name
62
+ )
63
+ end
127
64
 
128
- level = logging_level_from_string(logging_options[:level] || logging_options['level'])
129
- # limit the total log file to about 9 * 5 = 45 mb
130
- @logger = Logger.new(log_device)
131
- @logger.level = level
132
- @logger.formatter = proc do |severity, datetime, _progname, msg|
133
- # ISO 8601 format
134
- date_format = datetime.strftime('%Y-%m-%dT%H:%M:%S.%L%:z')
135
- "#{date_format} - [#{TCellAgent::VERSION}] - #{severity}[#{@logger_pid}]: #{msg}\n"
65
+ %i[debug info warn error].each do |method_name|
66
+ define_method(method_name) do |module_name, msg|
67
+ @native_agent.log_message(
68
+ method_name.to_s, msg, module_name
69
+ )
136
70
  end
71
+ end
72
+ end
137
73
 
138
- return @logger
74
+ @@ruby_logger = RubyLogger.new
139
75
 
140
- else
141
- @null_logger
142
- end
76
+ def self.logger
77
+ return @@ruby_logger unless defined?(@native_logger)
143
78
 
144
- @null_logger
79
+ @native_logger
145
80
  end
146
81
 
147
- def self.logger=(logger)
148
- @logger = logger
82
+ def self.native_logger=(native_agent)
83
+ @native_logger = NativeLogger.new(native_agent)
149
84
  end
150
85
  end
@@ -5,15 +5,14 @@ module TCellAgent
5
5
  module Patches
6
6
  def self.block?(request)
7
7
  TCellAgent::Instrumentation.safe_block('Checking patches blocking') do
8
- rust_policies = TCellAgent.policy(TCellAgent::PolicyTypes::RUST)
8
+ patches_policy = TCellAgent.policy(TCellAgent::PolicyTypes::PATCHES)
9
+ return false unless patches_policy.enabled
9
10
 
10
- if rust_policies && rust_policies.patches_enabled
11
- meta_data = TCellAgent::MetaData.from_request(request)
12
- block_request = rust_policies.block_request?(meta_data)
13
- request.env[TCellAgent::Instrumentation::TCELL_ID].patches_blocking_triggered = block_request
11
+ meta_data = TCellAgent::MetaData.for_patches(request)
12
+ block_request = patches_policy.block_request?(meta_data)
13
+ request.env[TCellAgent::Instrumentation::TCELL_ID].patches_blocking_triggered = block_request
14
14
 
15
- return block_request
16
- end
15
+ return block_request
17
16
  end
18
17
 
19
18
  false
@@ -0,0 +1,26 @@
1
+ require 'tcell_agent/policies/policy'
2
+
3
+ module TCellAgent
4
+ module Policies
5
+ class AppfirewallPolicy < Policy
6
+ def self.api_identifier
7
+ 'appsensor'
8
+ end
9
+
10
+ attr_accessor :enabled
11
+
12
+ def initialize(native_agent, enablements)
13
+ @native_agent = native_agent
14
+ @enabled = enablements['appfirewall'] || false
15
+ end
16
+
17
+ def check_appfirewall_injections(appsensor_meta)
18
+ return unless @enabled
19
+
20
+ TCellAgent::Instrumentation.safe_block('AppFirewall inspection') do
21
+ @native_agent.apply_appfirewall(appsensor_meta)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ require 'tcell_agent/policies/policy'
2
+
3
+ module TCellAgent
4
+ module Policies
5
+ class CommandInjectionPolicy < Policy
6
+ def self.api_identifier
7
+ 'cmdi'
8
+ end
9
+
10
+ attr_accessor :enabled
11
+
12
+ def initialize(native_agent, enablements)
13
+ @native_agent = native_agent
14
+ @enabled = enablements['cmdi'] || false
15
+ end
16
+
17
+ def block_command?(command, tcell_context)
18
+ return false unless @enabled && tcell_context
19
+
20
+ response = @native_agent.apply_cmdi(
21
+ command, tcell_context
22
+ )
23
+
24
+ !response['blocked'].nil? && response['blocked']
25
+ end
26
+ end
27
+ end
28
+ end
@@ -4,6 +4,10 @@ require 'tcell_agent/policies/policy'
4
4
  module TCellAgent
5
5
  module Policies
6
6
  class DataLossPolicy < Policy # rubocop:disable Metrics/ClassLength
7
+ def self.api_identifier
8
+ 'dlp'
9
+ end
10
+
7
11
  class FilterActions
8
12
  attr_accessor :body_event
9
13
  attr_accessor :body_redact
@@ -38,8 +42,9 @@ module TCellAgent
38
42
  attr_accessor :field_redact_body
39
43
  attr_accessor :field_alerts
40
44
 
41
- def initialize
45
+ def initialize(policies_json)
42
46
  init_options
47
+ from_json(policies_json) unless policies_json.nil? || policies_json.empty?
43
48
  end
44
49
 
45
50
  def init_options
@@ -192,19 +197,18 @@ module TCellAgent
192
197
  actions
193
198
  end
194
199
 
195
- def self.from_json(policy_json)
196
- return nil unless policy_json
200
+ def from_json(policy_json)
201
+ return unless policy_json
197
202
 
198
- policy = DataLossPolicy.new
199
- policy.policy_id = policy_json['policy_id']
200
- raise 'Policy ID missing' unless policy.policy_id
203
+ @policy_id = policy_json['policy_id']
204
+ raise 'Policy ID missing' unless @policy_id
201
205
 
202
206
  data_json = (policy_json['data'] || {})
203
207
 
204
208
  if data_json.key?('data_discovery')
205
209
  data_discovery_json = data_json['data_discovery']
206
- policy.database_discovery_enabled = data_discovery_json.fetch('database_enabled', false)
207
- policy.enabled = policy.database_discovery_enabled
210
+ @database_discovery_enabled = data_discovery_json.fetch('database_enabled', false)
211
+ @enabled = @database_discovery_enabled
208
212
  end
209
213
 
210
214
  if data_json.key?('session_id_protections')
@@ -212,9 +216,9 @@ module TCellAgent
212
216
  rule_id = session_id_protection.fetch('id', nil)
213
217
  filter_actions = DataLossPolicy.actions_from_json(session_id_protection)
214
218
  unless filter_actions.nil?
215
- policy.enabled = true
219
+ @enabled = true
216
220
  filter_actions.action_id = rule_id
217
- policy.session_id_filter_actions = filter_actions
221
+ @session_id_filter_actions = filter_actions
218
222
  end
219
223
  end
220
224
 
@@ -235,62 +239,58 @@ module TCellAgent
235
239
  next
236
240
  end
237
241
 
238
- next unless context && policy.request_filter_actions.key?(context) && variables && options
242
+ next unless context && @request_filter_actions.key?(context) && variables && options
239
243
  filter_actions = DataLossPolicy.actions_from_json(options)
240
244
  next if filter_actions.nil?
241
- policy.enabled = true
245
+ @enabled = true
242
246
  filter_actions.action_id = rule_id
243
247
  variables.each do |variable|
244
248
  route_ids.each do |route_id|
245
249
  if context == RequestProtectionManager::COOKIE
246
250
  # Case sensitive variable name
247
- policy.request_filter_actions[context][route_id][variable].add(filter_actions)
251
+ @request_filter_actions[context][route_id][variable].add(filter_actions)
248
252
  else
249
- policy.request_filter_actions[context][route_id][variable.downcase].add(filter_actions)
253
+ @request_filter_actions[context][route_id][variable.downcase].add(filter_actions)
250
254
  end
251
255
  end
252
256
  end
253
257
  end
254
258
  end
255
259
 
256
- if data_json.key?('db_protections')
257
- protections = data_json['db_protections']
258
- if protections
259
- protections.each do |protection_json|
260
- scope = protection_json.fetch('scope', nil)
261
- databases = protection_json.fetch('databases', ['*'])
262
- schemas = protection_json.fetch('schemas', ['*'])
263
- tables = protection_json.fetch('tables', ['*'])
264
- fields = protection_json.fetch('fields', nil)
265
- rule_id = protection_json.fetch('id', nil)
266
- actions = protection_json.fetch('actions', {})
267
- filter_actions = DataLossPolicy.actions_from_json(actions)
268
- route_ids = ['*']
260
+ return unless data_json.key?('db_protections')
261
+ protections = data_json['db_protections']
262
+ return unless protections
263
+ protections.each do |protection_json|
264
+ scope = protection_json.fetch('scope', nil)
265
+ databases = protection_json.fetch('databases', ['*'])
266
+ schemas = protection_json.fetch('schemas', ['*'])
267
+ tables = protection_json.fetch('tables', ['*'])
268
+ fields = protection_json.fetch('fields', nil)
269
+ rule_id = protection_json.fetch('id', nil)
270
+ actions = protection_json.fetch('actions', {})
271
+ filter_actions = DataLossPolicy.actions_from_json(actions)
272
+ route_ids = ['*']
273
+
274
+ if !scope.nil? && scope != 'global' && scope == 'route'
275
+ route_ids = protection_json.fetch('route_ids', [])
276
+ end
269
277
 
270
- if !scope.nil? && scope != 'global' && scope == 'route'
271
- route_ids = protection_json.fetch('route_ids', [])
272
- end
278
+ next if fields.nil? || filter_actions.nil?
273
279
 
274
- next if fields.nil? || filter_actions.nil?
275
-
276
- policy.enabled = true
277
- filter_actions.action_id = rule_id
278
- databases.each do |database|
279
- schemas.each do |schema|
280
- tables.each do |table|
281
- fields.each do |field|
282
- route_ids.each do |route_id|
283
- policy.database_actions[database][schema][table][field][route_id].add(filter_actions)
284
- end
285
- end
280
+ @enabled = true
281
+ filter_actions.action_id = rule_id
282
+ databases.each do |database|
283
+ schemas.each do |schema|
284
+ tables.each do |table|
285
+ fields.each do |field|
286
+ route_ids.each do |route_id|
287
+ @database_actions[database][schema][table][field][route_id].add(filter_actions)
286
288
  end
287
289
  end
288
290
  end
289
291
  end
290
292
  end
291
293
  end
292
-
293
- policy
294
294
  end
295
295
  end
296
296
  end