tcell_agent 1.1.12 → 2.2.0

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