tcell_agent 2.0.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +2 -2
  3. data/bin/tcell_agent +41 -150
  4. data/lib/tcell_agent/agent.rb +87 -52
  5. data/lib/tcell_agent/config_initializer.rb +63 -0
  6. data/lib/tcell_agent/configuration.rb +72 -267
  7. data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
  8. data/lib/tcell_agent/instrument_servers.rb +14 -18
  9. data/lib/tcell_agent/instrumentation/cmdi.rb +47 -15
  10. data/lib/tcell_agent/instrumentation/lfi.rb +72 -15
  11. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/file.rb +21 -0
  12. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/io.rb +75 -0
  13. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/kernel.rb +80 -0
  14. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/file.rb +21 -0
  15. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/io.rb +75 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/kernel.rb +80 -0
  17. data/lib/tcell_agent/instrumentation.rb +14 -6
  18. data/lib/tcell_agent/logger.rb +3 -4
  19. data/lib/tcell_agent/policies/command_injection_policy.rb +1 -1
  20. data/lib/tcell_agent/policies/dataloss_policy.rb +15 -8
  21. data/lib/tcell_agent/policies/headers_policy.rb +2 -2
  22. data/lib/tcell_agent/policies/patches_policy.rb +8 -4
  23. data/lib/tcell_agent/policies/policies_manager.rb +1 -0
  24. data/lib/tcell_agent/policies/policy_polling.rb +4 -3
  25. data/lib/tcell_agent/rails/auth/authlogic.rb +49 -44
  26. data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
  27. data/lib/tcell_agent/rails/auth/devise.rb +103 -102
  28. data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
  29. data/lib/tcell_agent/rails/auth/doorkeeper.rb +54 -57
  30. data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
  31. data/lib/tcell_agent/rails/better_ip.rb +7 -19
  32. data/lib/tcell_agent/rails/csrf_exception.rb +0 -8
  33. data/lib/tcell_agent/rails/dlp/process_request.rb +5 -0
  34. data/lib/tcell_agent/rails/dlp.rb +58 -56
  35. data/lib/tcell_agent/rails/dlp_handler.rb +9 -10
  36. data/lib/tcell_agent/rails/js_agent_insert.rb +2 -3
  37. data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -1
  38. data/lib/tcell_agent/rails/middleware/global_middleware.rb +3 -4
  39. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
  40. data/lib/tcell_agent/rails/{on_start.rb → railties/tcell_agent_railties.rb} +9 -16
  41. data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
  42. data/lib/tcell_agent/rails/routes/grape.rb +5 -12
  43. data/lib/tcell_agent/rails/routes.rb +6 -9
  44. data/lib/tcell_agent/rails/settings_reporter.rb +3 -6
  45. data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -7
  46. data/lib/tcell_agent/routes/table.rb +3 -0
  47. data/lib/tcell_agent/rust/agent_config.rb +62 -33
  48. data/lib/tcell_agent/rust/{libtcellagent-4.14.0.so → libtcellagent-alpine.so} +0 -0
  49. data/lib/tcell_agent/rust/{libtcellagent-4.14.0.dylib → libtcellagent-x64.dll} +0 -0
  50. data/lib/tcell_agent/rust/{libtcellagent-alpine-4.14.0.so → libtcellagent.dylib} +0 -0
  51. data/lib/tcell_agent/rust/libtcellagent.so +0 -0
  52. data/lib/tcell_agent/rust/models.rb +9 -0
  53. data/lib/tcell_agent/rust/native_agent.rb +61 -51
  54. data/lib/tcell_agent/rust/native_library.rb +8 -10
  55. data/lib/tcell_agent/sensor_events/server_agent.rb +3 -100
  56. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +1 -0
  57. data/lib/tcell_agent/servers/puma.rb +30 -13
  58. data/lib/tcell_agent/servers/rack_puma_handler.rb +33 -0
  59. data/lib/tcell_agent/servers/rails_server.rb +4 -4
  60. data/lib/tcell_agent/servers/unicorn.rb +1 -1
  61. data/lib/tcell_agent/servers/webrick.rb +12 -3
  62. data/lib/tcell_agent/settings_reporter.rb +0 -93
  63. data/lib/tcell_agent/sinatra.rb +1 -0
  64. data/lib/tcell_agent/tcell_context.rb +16 -7
  65. data/lib/tcell_agent/utils/headers.rb +0 -1
  66. data/lib/tcell_agent/utils/strings.rb +2 -2
  67. data/lib/tcell_agent/version.rb +1 -1
  68. data/lib/tcell_agent.rb +8 -16
  69. data/spec/cruby_spec_helper.rb +26 -0
  70. data/spec/lib/tcell_agent/configuration_spec.rb +62 -212
  71. data/spec/lib/tcell_agent/instrument_servers_spec.rb +95 -0
  72. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
  73. data/spec/lib/tcell_agent/{cmdi_spec.rb → instrumentation/cmdi_spec.rb} +50 -0
  74. data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +211 -272
  75. data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +213 -223
  76. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +95 -61
  77. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +120 -2
  78. data/spec/lib/tcell_agent/patches_spec.rb +2 -1
  79. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +1 -2
  80. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +5 -6
  81. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +21 -2
  82. data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +1 -1
  83. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +13 -8
  84. data/spec/lib/tcell_agent/rails/better_ip_spec.rb +9 -11
  85. data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +6 -6
  86. data/spec/lib/tcell_agent/rails/dlp_spec.rb +1 -0
  87. data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +10 -2
  88. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -1
  89. data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +4 -4
  90. data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
  91. data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -89
  92. data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
  93. data/spec/spec_helper.rb +9 -1
  94. data/spec/support/builders.rb +8 -7
  95. data/spec/support/server_mocks/passenger_mock.rb +7 -0
  96. data/spec/support/server_mocks/puma_mock.rb +21 -0
  97. data/spec/support/server_mocks/rails_mock.rb +7 -0
  98. data/spec/support/server_mocks/thin_mock.rb +7 -0
  99. data/spec/support/server_mocks/unicorn_mock.rb +11 -0
  100. data/spec/support/shared_spec.rb +29 -0
  101. data/tcell_agent.gemspec +14 -14
  102. metadata +46 -29
  103. data/Rakefile +0 -18
  104. data/lib/tcell_agent/authlogic.rb +0 -23
  105. data/lib/tcell_agent/config/unknown_options.rb +0 -119
  106. data/lib/tcell_agent/devise.rb +0 -33
  107. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +0 -25
  108. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +0 -123
  109. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +0 -159
  110. data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
  111. data/lib/tcell_agent/rust/tcellagent-4.14.0.dll +0 -0
  112. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
@@ -1,159 +0,0 @@
1
- module Kernel
2
- class << self
3
- alias_method :tcell_original_1_open, :open
4
- def open(*args, &block)
5
- path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
6
-
7
- if path && TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
8
- raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
9
- end
10
-
11
- cmd = TCellAgent::Cmdi.parse_command_from_open(*args)
12
- if cmd && TCellAgent::Cmdi.block_command?(cmd)
13
- raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
14
- end
15
-
16
- tcell_original_1_open(*args, &block)
17
- end
18
-
19
- alias_method :tcell_original_1_gets, :gets
20
- def gets(*args, &block)
21
- path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode_argf
22
-
23
- if TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
24
- raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
25
- end
26
-
27
- tcell_original_1_gets(*args, &block)
28
- end
29
-
30
- alias_method :tcell_original_readline, :readline
31
- def readline(*args, &block)
32
- path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode_argf
33
-
34
- if TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
35
- raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
36
- end
37
-
38
- tcell_original_readline(*args, &block)
39
- end
40
-
41
- alias_method :tcell_original_1_spawn, :spawn
42
- def spawn(*args)
43
- cmd = TCellAgent::Cmdi.parse_command(*args)
44
- if TCellAgent::Cmdi.block_command?(cmd)
45
- raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
46
- end
47
-
48
- tcell_original_1_spawn(*args)
49
- end
50
-
51
- alias_method :tcell_original_1_system, :system
52
- def system(*args)
53
- cmd = TCellAgent::Cmdi.parse_command(*args)
54
- if TCellAgent::Cmdi.block_command?(cmd)
55
- raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
56
- end
57
-
58
- tcell_original_1_system(*args)
59
- end
60
- end
61
-
62
- alias_method :tcell_original_backtick, :`
63
- def `(cmd)
64
- if TCellAgent::Cmdi.block_command?(cmd)
65
- raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
66
- end
67
-
68
- tcell_original_backtick(cmd)
69
- end
70
-
71
- alias_method :tcell_original_2_open, :open
72
- def open(*args, &block)
73
- path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
74
-
75
- if path && TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
76
- raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
77
- end
78
-
79
- cmd = TCellAgent::Cmdi.parse_command_from_open(*args)
80
- if cmd && TCellAgent::Cmdi.block_command?(cmd)
81
- raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
82
- end
83
-
84
- tcell_original_2_open(*args, &block)
85
- end
86
-
87
- alias_method :tcell_original_2_gets, :gets
88
- def gets(*args, &block)
89
- path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode_argf
90
-
91
- if TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
92
- raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
93
- end
94
-
95
- tcell_original_2_gets(*args, &block)
96
- end
97
-
98
- alias_method :tcell_original_readline, :readline
99
- def readline(*args, &block)
100
- path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode_argf
101
-
102
- if TCellAgent::Instrumentation::Lfi.block_file_access?(path, mode)
103
- raise IOError, "tCell.io Agent: Attempted access to file #{path} with mode #{mode} denied"
104
- end
105
-
106
- tcell_original_readline(*args, &block)
107
- end
108
-
109
- alias_method :tcell_original_2_spawn, :spawn
110
- def spawn(*args)
111
- cmd = TCellAgent::Cmdi.parse_command(*args)
112
- if TCellAgent::Cmdi.block_command?(cmd)
113
- raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
114
- end
115
-
116
- tcell_original_2_spawn(*args)
117
- end
118
-
119
- alias_method :tcell_original_2_system, :system
120
- def system(*args)
121
- cmd = TCellAgent::Cmdi.parse_command(*args)
122
- if TCellAgent::Cmdi.block_command?(cmd)
123
- raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
124
- end
125
-
126
- tcell_original_2_system(*args)
127
- end
128
- end
129
-
130
- if TCellAgent.configuration.should_instrument_cmdi_exec?
131
- module Kernel
132
- class << self
133
- alias_method :tcell_original_exec, :exec
134
- def exec(*args)
135
- cmd = TCellAgent::Cmdi.parse_command(*args)
136
- if TCellAgent::Cmdi.block_command?(cmd)
137
- raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
138
- end
139
-
140
- tcell_original_exec(*args)
141
- end
142
- end
143
-
144
- alias_method :tcell_original_exec, :exec
145
-
146
- private
147
-
148
- def exec(*args)
149
- cmd = TCellAgent::Cmdi.parse_command(*args)
150
- if TCellAgent::Cmdi.block_command?(cmd)
151
- raise "tCell.io Agent: Command not allowed by policy: #{cmd}"
152
- end
153
-
154
- tcell_original_exec(*args)
155
- end
156
- end
157
- else
158
- TCellAgent.logger.debug('Disabling cmdi Kernel::exec instrumentation', 'TCellAgent::Cmdi')
159
- end
@@ -1,12 +0,0 @@
1
- module TCellAgent
2
- class TCellAgentStartupRailtie < Rails::Railtie
3
- # TCellAgent config can be specified thru Rails initializer's
4
- # (https://guides.rubyonrails.org/v2.3/configuring.html#using-initializers)
5
- # so those need to run first before the agent is started
6
- initializer :start_tcell_agent,
7
- :after => :load_config_initializers,
8
- :before => :tcell_instrument_auth_frameworks do |_app|
9
- TCellAgent.thread_agent.start('Unicorn')
10
- end
11
- end
12
- end
@@ -1,195 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module TCellAgent
4
- module Config
5
- describe Validate do
6
- describe '.get_unknown_options' do
7
- context 'with an unknown tcell environment variable set' do
8
- it 'should return a message about the unknown variable' do
9
- orig_allow_ap = ENV.fetch('TCELL_AGENT_ALLOW_PAYLOADS', nil)
10
- orig_demomode = ENV.fetch('TCELL_DEMOMODE', nil)
11
- orig_agent_home = ENV.fetch('TCELL_AGENT_HOME', nil)
12
- orig_agent_log_dir = ENV.fetch('TCELL_AGENT_LOG_DIR', nil)
13
- orig_agent_config = ENV.fetch('TCELL_AGENT_CONFIG', nil)
14
- orig_agent_app_id = ENV.fetch('TCELL_AGENT_APP_ID', nil)
15
- orig_agent_api_key = ENV.fetch('TCELL_AGENT_API_KEY', nil)
16
- orig_agent_host_identifier = ENV.fetch('TCELL_AGENT_HOST_IDENTIFIER', nil)
17
- orig_input_url = ENV.fetch('TCELL_INPUT_URL', nil)
18
- orig_hmac_key = ENV.fetch('TCELL_HMAC_KEY', nil)
19
- orig_api_url = ENV.fetch('TCELL_API_URL', nil)
20
- orig_password_hmac_key = ENV.fetch('TCELL_PASSWORD_HMAC_KEY', nil)
21
-
22
- ENV['TCELL_HACK'] = 'hack the system'
23
- ENV['TCELL_AGENT_ALLOW_PAYLOADS'] = 'valid'
24
- ENV['TCELL_DEMOMODE'] = 'valid'
25
- ENV['TCELL_AGENT_HOME'] = 'valid'
26
- ENV['TCELL_AGENT_LOG_DIR'] = 'valid'
27
- ENV['TCELL_AGENT_CONFIG'] = 'valid'
28
- ENV['TCELL_AGENT_APP_ID'] = 'valid'
29
- ENV['TCELL_AGENT_API_KEY'] = 'valid'
30
- ENV['TCELL_AGENT_HOST_IDENTIFIER'] = 'valid'
31
- ENV['TCELL_INPUT_URL'] = 'valid'
32
- ENV['TCELL_HMAC_KEY'] = 'valid'
33
- ENV['TCELL_API_URL'] = 'valid'
34
- ENV['TCELL_PASSWORD_HMAC_KEY'] = 'valid'
35
-
36
- messages = Validate.get_unknown_options(nil)
37
-
38
- ENV.delete 'TCELL_HACK'
39
-
40
- if orig_allow_ap
41
- ENV['TCELL_AGENT_ALLOW_PAYLOADS'] = orig_allow_ap
42
- else
43
- ENV.delete 'TCELL_AGENT_ALLOW_PAYLOADS'
44
- end
45
- if orig_demomode
46
- ENV['TCELL_DEMOMODE'] = orig_demomode
47
- else
48
- ENV.delete 'TCELL_DEMOMODE'
49
- end
50
- if orig_agent_home
51
- ENV['TCELL_AGENT_HOME'] = orig_agent_home
52
- else
53
- ENV.delete 'TCELL_AGENT_HOME'
54
- end
55
- if orig_agent_log_dir
56
- ENV['TCELL_AGENT_LOG_DIR'] = orig_agent_log_dir
57
- else
58
- ENV.delete 'TCELL_AGENT_LOG_DIR'
59
- end
60
- if orig_agent_config
61
- ENV['TCELL_AGENT_CONFIG'] = orig_agent_config
62
- else
63
- ENV.delete 'TCELL_AGENT_CONFIG'
64
- end
65
- if orig_agent_app_id
66
- ENV['TCELL_AGENT_APP_ID'] = orig_agent_app_id
67
- else
68
- ENV.delete 'TCELL_AGENT_APP_ID'
69
- end
70
- if orig_agent_api_key
71
- ENV['TCELL_AGENT_API_KEY'] = orig_agent_api_key
72
- else
73
- ENV.delete 'TCELL_AGENT_API_KEY'
74
- end
75
- if orig_agent_host_identifier
76
- ENV['TCELL_AGENT_HOST_IDENTIFIER'] = orig_agent_host_identifier
77
- else
78
- ENV.delete 'TCELL_AGENT_HOST_IDENTIFIER'
79
- end
80
- if orig_input_url
81
- ENV['TCELL_INPUT_URL'] = orig_input_url
82
- else
83
- ENV.delete 'TCELL_INPUT_URL'
84
- end
85
- if orig_hmac_key
86
- ENV['TCELL_HMAC_KEY'] = orig_hmac_key
87
- else
88
- ENV.delete 'TCELL_HMAC_KEY'
89
- end
90
- if orig_password_hmac_key
91
- ENV['TCELL_PASSWORD_HMAC_KEY'] = orig_password_hmac_key
92
- else
93
- ENV.delete 'TCELL_PASSWORD_HMAC_KEY'
94
- end
95
- if orig_api_url
96
- ENV['TCELL_API_URL'] = orig_api_url
97
- else
98
- ENV.delete 'TCELL_API_URL'
99
- end
100
-
101
- expect(messages.sort).to eq(
102
- [
103
- 'Unrecognized environment parameter (TCELL_*) found: TCELL_HACK'
104
- ]
105
- )
106
- end
107
- end
108
-
109
- context 'with a config json with all options including some extra ones' do
110
- it 'should report the extra options in messages' do
111
- config_json = {
112
- 'first_level' => 'boo',
113
- 'version' => 1,
114
- 'applications' => [
115
- {
116
- 'second_level' => 'boo',
117
- 'name' => 'name',
118
- 'app_id' => 'app id',
119
- 'api_key' => 'api key',
120
- 'fetch_policies_from_tcell' => true,
121
- 'preload_policy_filename' => 'preload policy filename',
122
- 'log_dir' => 'custom log dir',
123
- 'logging_options' => {
124
- 'logging_level' => 'boo',
125
- 'enabled' => true,
126
- 'level' => 'DEBUG',
127
- 'filename' => 'filename'
128
- },
129
- 'tcell_api_url' => 'tcell api url',
130
- 'tcell_input_url' => 'tcell input url',
131
- 'host_identifier' => 'host identifier',
132
- 'hipaaSafeMode' => 'hipaa safe mode',
133
- 'hmac_key' => 'hmac key',
134
- 'password_hmac_key' => 'password_hmac_key',
135
- 'js_agent_api_base_url' => 'js agent api base url',
136
- 'js_agent_url' => 'js agent url',
137
- 'max_csp_header_bytes' => 512,
138
- 'event_batch_size_limit' => 50,
139
- 'allow_payloads' => true,
140
- 'data_exposure' => {
141
- 'data_ex_level' => 'boo',
142
- 'max_data_ex_db_records_per_request' => 10_000
143
- },
144
- 'reverse_proxy' => true,
145
- 'reverse_proxy_ip_address_header' => 'reverse proxy ip address header',
146
- 'demomode' => true,
147
- # Ruby only
148
- 'disable_all' => false,
149
- 'enabled' => true,
150
- 'enable_event_manager' => true,
151
- 'enable_policy_polling' => true,
152
- 'enable_instrumentation' => true,
153
- 'enable_intercept_requests' => true,
154
- 'instrument_for_events' => true,
155
- 'enabled_instrumentations' => {
156
- 'enabled_instrumentations_level' => 'blah',
157
- 'doorkeeper' => true,
158
- 'devise' => true,
159
- 'authlogic' => true
160
- }
161
- }
162
- ]
163
- }
164
-
165
- messages = Validate.get_unknown_options(config_json)
166
-
167
- expect(messages.sort).to eq(
168
- [
169
- 'Unrecognized config setting key: data_ex_level',
170
- 'Unrecognized config setting key: enabled_instrumentations_level',
171
- 'Unrecognized config setting key: first_level',
172
- 'Unrecognized config setting key: logging_level',
173
- 'Unrecognized config setting key: second_level'
174
- ]
175
- )
176
- end
177
- end
178
-
179
- context 'with a config json that has more than one application' do
180
- it 'should report the misconfiguration' do
181
- config_json = { 'version' => 1, 'applications' => [{}, {}] }
182
-
183
- messages = Validate.get_unknown_options(config_json)
184
-
185
- expect(messages.sort).to eq(
186
- [
187
- 'Multiple applications detected in config file'
188
- ]
189
- )
190
- end
191
- end
192
- end
193
- end
194
- end
195
- end