tcell_agent 1.1.11 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  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 -7
  9. data/lib/tcell_agent/configuration.rb +39 -118
  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 +29 -25
  15. data/lib/tcell_agent/instrumentation/lfi.rb +84 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +25 -0
  17. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +131 -0
  18. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +102 -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 +35 -19
  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 +10 -9
  47. data/lib/tcell_agent/rails/routes/grape.rb +4 -12
  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.18.0.dylib} +0 -0
  54. data/lib/tcell_agent/rust/{libtcellagent-1.3.2.so → libtcellagent-4.18.0.so} +0 -0
  55. data/lib/tcell_agent/rust/libtcellagent-alpine-4.18.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.18.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 +41 -15
  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/config/unknown_options_spec.rb +0 -18
  80. data/spec/lib/tcell_agent/configuration_spec.rb +4 -140
  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/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 +64 -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/cmdi_spec.rb +0 -736
  152. data/spec/lib/tcell_agent/instrumentation_spec.rb +0 -225
  153. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +0 -517
  154. data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +0 -22
  155. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +0 -293
  156. data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +0 -198
  157. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +0 -180
  158. data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +0 -116
  159. data/spec/lib/tcell_agent/rust/models_spec.rb +0 -120
  160. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +0 -704
  161. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +0 -45
  162. data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +0 -272
  163. data/spec/lib/tcell_agent/utils/bounded_queue_spec.rb +0 -52
  164. data/spec/lib/tcell_agent/utils/passwords_spec.rb +0 -143
@@ -0,0 +1,435 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kernel do
4
+ before(:each) do
5
+ native_agent = double('native_agent')
6
+ @command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new(
7
+ native_agent, {}
8
+ )
9
+ end
10
+
11
+ describe '.backtick' do
12
+ context 'empty command' do
13
+ it 'should raise Errno::ENOENT' do
14
+ expect do
15
+ ``
16
+ end.to raise_error(Errno::ENOENT)
17
+ end
18
+ end
19
+
20
+ context 'with a non blocked command present' do
21
+ before(:each) do
22
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
23
+ end
24
+
25
+ context 'with command injection disabled' do
26
+ it 'should execute the command' do
27
+ expect(TCellAgent).to receive(:policy).with(
28
+ TCellAgent::PolicyTypes::COMMANDINJECTION
29
+ ).and_return(@command_injection_policy)
30
+ expect(@command_injection_policy).to receive(:enabled).and_return(false)
31
+ expect(@command_injection_policy).to_not receive(:block_command?)
32
+
33
+ `echo test`
34
+ end
35
+ end
36
+
37
+ context 'with command injection enabled' do
38
+ it 'should execute the command' do
39
+ expect(TCellAgent).to receive(:policy).with(
40
+ TCellAgent::PolicyTypes::COMMANDINJECTION
41
+ ).and_return(@command_injection_policy)
42
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
43
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(false)
44
+
45
+ `echo test`
46
+ end
47
+ end
48
+ end
49
+
50
+ context 'with a blocked command present' do
51
+ context 'with command injection enabled' do
52
+ it 'should raise a RuntimeError' do
53
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
54
+ expect(TCellAgent).to receive(:policy).with(
55
+ TCellAgent::PolicyTypes::COMMANDINJECTION
56
+ ).and_return(@command_injection_policy)
57
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
58
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(true)
59
+
60
+ expect do
61
+ `echo test`
62
+ end.to raise_error(RuntimeError)
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ describe '%x methods' do
69
+ context 'empty command' do
70
+ it 'should raise RuntimeError' do
71
+ expect do
72
+ ``
73
+ end.to raise_error(Errno::ENOENT)
74
+ end
75
+ end
76
+
77
+ context 'with a non blocked command present' do
78
+ before(:each) do
79
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
80
+ end
81
+
82
+ context 'with command injection disabled' do
83
+ it 'should execute the command' do
84
+ expect(TCellAgent).to receive(:policy).with(
85
+ TCellAgent::PolicyTypes::COMMANDINJECTION
86
+ ).and_return(@command_injection_policy)
87
+ expect(@command_injection_policy).to receive(:enabled).and_return(false)
88
+ expect(@command_injection_policy).to_not receive(:block_command?)
89
+
90
+ `echo test`
91
+ end
92
+ end
93
+
94
+ context 'with command injection enabled' do
95
+ it 'should execute the command' do
96
+ expect(TCellAgent).to receive(:policy).with(
97
+ TCellAgent::PolicyTypes::COMMANDINJECTION
98
+ ).and_return(@command_injection_policy)
99
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
100
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(false)
101
+
102
+ `echo test`
103
+ end
104
+ end
105
+ end
106
+
107
+ context 'with a blocked command present' do
108
+ context 'with command injection enabled' do
109
+ it 'should raise a RuntimeError' do
110
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
111
+ expect(TCellAgent).to receive(:policy).with(
112
+ TCellAgent::PolicyTypes::COMMANDINJECTION
113
+ ).and_return(@command_injection_policy)
114
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
115
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(true)
116
+
117
+ expect do
118
+ `echo test`
119
+ end.to raise_error(RuntimeError)
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ describe '::open and #open' do
126
+ context 'empty command' do
127
+ it 'should raise an error' do
128
+ expect do
129
+ Kernel.open
130
+ end.to raise_error(ArgumentError)
131
+ expect do
132
+ Kernel.open(nil)
133
+ end.to raise_error(TypeError)
134
+ expect do
135
+ Kernel.open('')
136
+ end.to raise_error(Errno::ENOENT)
137
+ end
138
+ end
139
+
140
+ context 'name starts with a | operator' do
141
+ context 'with an empty or invalid command' do
142
+ it 'should raise an error' do
143
+ expect do
144
+ Kernel.open('|')
145
+ end.to raise_error(Errno::ENOENT)
146
+
147
+ expect do
148
+ Kernel.open('|invalid command')
149
+ end.to raise_error(Errno::ENOENT)
150
+
151
+ expect do
152
+ Kernel.open('|invalid command', 10)
153
+ end.to raise_error(Errno::ENOENT)
154
+ end
155
+ end
156
+ context 'with a valid command' do
157
+ it 'should execute the command' do
158
+ expect(Kernel.open('|echo test').read).to eq("test\n")
159
+ end
160
+ end
161
+ context 'with a non blocked command present' do
162
+ before(:each) do
163
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
164
+ end
165
+ context 'with command injection disabled' do
166
+ it 'should execute the command' do
167
+ expect(@command_injection_policy.enabled).to eq(false)
168
+
169
+ expect(TCellAgent).to receive(:policy).with(
170
+ TCellAgent::PolicyTypes::COMMANDINJECTION
171
+ ).and_return(@command_injection_policy)
172
+ expect(@command_injection_policy).to receive(:enabled).and_call_original
173
+ expect(@command_injection_policy).to_not receive(:block_command?)
174
+
175
+ expect(Kernel.open('|echo test').read).to eq("test\n")
176
+ end
177
+ end
178
+
179
+ context 'with command injection enabled' do
180
+ it 'should execute the command' do
181
+ expect(TCellAgent).to receive(:policy).with(
182
+ TCellAgent::PolicyTypes::COMMANDINJECTION
183
+ ).and_return(@command_injection_policy)
184
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
185
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(false)
186
+
187
+ expect(Kernel.open('|echo test').read).to eq("test\n")
188
+ end
189
+ end
190
+ end
191
+
192
+ context 'with a blocked command present' do
193
+ context 'with command injection enabled' do
194
+ it 'should raise a RuntimeError' do
195
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
196
+
197
+ expect(TCellAgent).to receive(:policy).with(
198
+ TCellAgent::PolicyTypes::COMMANDINJECTION
199
+ ).and_return(@command_injection_policy)
200
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
201
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(true)
202
+
203
+ expect do
204
+ Kernel.open('|echo test')
205
+ end.to raise_error(RuntimeError)
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
211
+ describe '.spawn and Kernel.spawn' do
212
+ context 'empty command' do
213
+ it 'should raise an error' do
214
+ expect do
215
+ spawn
216
+ end.to raise_error(ArgumentError)
217
+ expect do
218
+ Kernel.spawn
219
+ end.to raise_error(ArgumentError)
220
+ expect do
221
+ spawn(nil)
222
+ end.to raise_error(TypeError)
223
+ expect do
224
+ Kernel.spawn(nil)
225
+ end.to raise_error(TypeError)
226
+ expect do
227
+ spawn('')
228
+ end.to raise_error(Errno::ENOENT)
229
+ expect do
230
+ Kernel.spawn('')
231
+ end.to raise_error(Errno::ENOENT)
232
+ end
233
+ end
234
+
235
+ context 'non existent command' do
236
+ it 'should raise error' do
237
+ expect do
238
+ spawn('foobar')
239
+ end.to raise_error(Errno::ENOENT)
240
+ expect do
241
+ Kernel.spawn('foobar')
242
+ end.to raise_error(Errno::ENOENT)
243
+ end
244
+ end
245
+
246
+ context 'with a valid command' do
247
+ it 'should execute command' do
248
+ pid = spawn('echo test > /dev/null 2>&1')
249
+ expect(pid).to_not be_nil
250
+
251
+ pid = spawn(RbConfig.ruby, "-e'Hello World!'", '>', '/dev/null', '2>&1')
252
+ expect(pid).to_not be_nil
253
+
254
+ pid = Kernel.spawn('echo test > /dev/null 2>&1')
255
+ expect(pid).to_not be_nil
256
+
257
+ pid = Kernel.spawn(RbConfig.ruby, "-e'Hello World!'", '>', '/dev/null', '2>&1')
258
+ expect(pid).to_not be_nil
259
+ end
260
+ end
261
+
262
+ context 'with a non blocked command present' do
263
+ before(:each) do
264
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
265
+ end
266
+
267
+ context 'with command injection disabled' do
268
+ it 'should execute the command' do
269
+ expect(TCellAgent).to receive(:policy).with(
270
+ TCellAgent::PolicyTypes::COMMANDINJECTION
271
+ ).and_return(@command_injection_policy, @command_injection_policy)
272
+ expect(@command_injection_policy).to receive(:enabled).and_return(false, false)
273
+ expect(@command_injection_policy).to_not receive(:block_command?)
274
+
275
+ spawn('echo test > /dev/null 2>&1')
276
+ Kernel.spawn('echo test > /dev/null 2>&1')
277
+ end
278
+ end
279
+
280
+ context 'with command injection enabled' do
281
+ it 'should execute the command' do
282
+ expect(TCellAgent).to receive(:policy).with(
283
+ TCellAgent::PolicyTypes::COMMANDINJECTION
284
+ ).and_return(@command_injection_policy, @command_injection_policy)
285
+ expect(@command_injection_policy).to receive(:enabled).and_return(true, true)
286
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test > /dev/null 2>&1', nil).and_return(false, false)
287
+
288
+ spawn('echo test > /dev/null 2>&1')
289
+ Kernel.spawn('echo test > /dev/null 2>&1')
290
+ end
291
+ end
292
+ end
293
+
294
+ context 'with a blocked command present' do
295
+ context 'with command injection enabled' do
296
+ it 'should raise a RuntimeError' do
297
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
298
+ expect(TCellAgent).to receive(:policy).with(
299
+ TCellAgent::PolicyTypes::COMMANDINJECTION
300
+ ).and_return(@command_injection_policy, @command_injection_policy)
301
+ expect(@command_injection_policy).to receive(:enabled).and_return(true, true)
302
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(true, true)
303
+
304
+ expect do
305
+ spawn('echo test')
306
+ end.to raise_error(RuntimeError)
307
+ expect do
308
+ Kernel.spawn('echo test')
309
+ end.to raise_error(RuntimeError)
310
+ end
311
+ end
312
+ end
313
+ end
314
+
315
+ describe '.system and Kernel.system' do
316
+ context 'empty command' do
317
+ it 'should raise an error' do
318
+ expect do
319
+ system
320
+ end.to raise_error(ArgumentError)
321
+ expect do
322
+ Kernel.system
323
+ end.to raise_error(ArgumentError)
324
+ expect do
325
+ system(nil)
326
+ end.to raise_error(TypeError)
327
+ expect do
328
+ Kernel.system(nil)
329
+ end.to raise_error(TypeError)
330
+ expect(system('')).to be_nil
331
+ expect(Kernel.system('')).to be_nil
332
+ end
333
+ end
334
+
335
+ context 'non existent command' do
336
+ it 'should return nil' do
337
+ expect(system('foobar')).to be_nil
338
+ expect(Kernel.system('foobar')).to be_nil
339
+ end
340
+ end
341
+
342
+ context 'with a valid command' do
343
+ it 'should execute command' do
344
+ pid = system('echo test > /dev/null 2>&1')
345
+ expect(pid).to eq(true)
346
+
347
+ pid = system(RbConfig.ruby, "-e'Hello World!'", '>', '/dev/null', '2>&1')
348
+ expect(pid).to eq(true)
349
+
350
+ pid = Kernel.system('echo test > /dev/null 2>&1')
351
+ expect(pid).to eq(true)
352
+
353
+ pid = Kernel.system(RbConfig.ruby, "-e'Hello World!'", '>', '/dev/null', '2>&1')
354
+ expect(pid).to eq(true)
355
+ end
356
+ end
357
+
358
+ context 'with a non blocked command present' do
359
+ before(:each) do
360
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
361
+ end
362
+
363
+ context 'with command injection disabled' do
364
+ it 'should execute the command' do
365
+ expect(TCellAgent).to receive(:policy).with(
366
+ TCellAgent::PolicyTypes::COMMANDINJECTION
367
+ ).and_return(@command_injection_policy, @command_injection_policy)
368
+ expect(@command_injection_policy).to receive(:enabled).and_return(false, false)
369
+ expect(@command_injection_policy).to_not receive(:block_command?)
370
+
371
+ system('echo test > /dev/null 2>&1')
372
+ Kernel.system('echo test > /dev/null 2>&1')
373
+ end
374
+ end
375
+
376
+ context 'with command injection enabled' do
377
+ it 'should execute the command' do
378
+ expect(TCellAgent).to receive(:policy).with(
379
+ TCellAgent::PolicyTypes::COMMANDINJECTION
380
+ ).and_return(@command_injection_policy, @command_injection_policy)
381
+ expect(@command_injection_policy).to receive(:enabled).and_return(true, true)
382
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test > /dev/null 2>&1', nil).and_return(false, false)
383
+
384
+ system('echo test > /dev/null 2>&1')
385
+ Kernel.system('echo test > /dev/null 2>&1')
386
+ end
387
+ end
388
+ end
389
+
390
+ context 'with a blocked command present' do
391
+ context 'with command injection enabled' do
392
+ it 'should raise a RuntimeError' do
393
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
394
+
395
+ expect(TCellAgent).to receive(:policy).with(
396
+ TCellAgent::PolicyTypes::COMMANDINJECTION
397
+ ).and_return(@command_injection_policy, @command_injection_policy)
398
+ expect(@command_injection_policy).to receive(:enabled).and_return(true, true)
399
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(true, true)
400
+
401
+ expect do
402
+ system('echo test')
403
+ end.to raise_error(RuntimeError)
404
+ expect do
405
+ Kernel.system('echo test')
406
+ end.to raise_error(RuntimeError)
407
+ end
408
+ end
409
+ end
410
+ end
411
+
412
+ describe '.exec' do
413
+ # can only test this case since exec replaces current process with new process
414
+ context 'with a blocked command present' do
415
+ context 'with command injection enabled' do
416
+ it 'should raise a RuntimeError' do
417
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
418
+
419
+ expect(TCellAgent).to receive(:policy).with(
420
+ TCellAgent::PolicyTypes::COMMANDINJECTION
421
+ ).and_return(@command_injection_policy, @command_injection_policy)
422
+ expect(@command_injection_policy).to receive(:enabled).and_return(true, true)
423
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(true, true)
424
+
425
+ expect do
426
+ exec('echo test')
427
+ end.to raise_error(RuntimeError)
428
+ expect do
429
+ Kernel.exec('echo test')
430
+ end.to raise_error(RuntimeError)
431
+ end
432
+ end
433
+ end
434
+ end
435
+ end
@@ -0,0 +1,201 @@
1
+ require 'spec_helper'
2
+
3
+ module TCellAgent
4
+ module Cmdi
5
+ describe '.parse_command' do
6
+ context 'with env' do
7
+ before(:each) do
8
+ @env = { 'TCELL_VAR' => 'enabled' }
9
+ end
10
+
11
+ context 'with string command' do
12
+ it 'should parse the command properly' do
13
+ cmd = TCellAgent::Cmdi.parse_command(@env, 'echo')
14
+ expect(cmd).to eq('echo')
15
+
16
+ cmd = TCellAgent::Cmdi.parse_command(@env, 'echo', :unsetenv_others => true)
17
+ expect(cmd).to eq('echo')
18
+ end
19
+ end
20
+
21
+ context 'with string command and arguments' do
22
+ it 'should parse the command' do
23
+ cmd = TCellAgent::Cmdi.parse_command(@env, 'echo', 'test', :unsetenv_others => true)
24
+ expect(cmd).to eq('echo test')
25
+
26
+ cmd = TCellAgent::Cmdi.parse_command(@env, 'echo', 'test', 'one', :unsetenv_others => true)
27
+ expect(cmd).to eq('echo test one')
28
+
29
+ cmd = TCellAgent::Cmdi.parse_command(
30
+ @env,
31
+ 'magick',
32
+ '-size',
33
+ '320x85',
34
+ 'canvas:none',
35
+ '-font',
36
+ 'Bookman-DemiItalic',
37
+ '-draw',
38
+ "\"text 25,60 \'Magick\'\"",
39
+ :unsetenv_others => true
40
+ )
41
+ expect(cmd).to eq(
42
+ "magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
43
+ )
44
+ end
45
+ end
46
+
47
+ context 'with array command' do
48
+ it 'should parse the command properly' do
49
+ cmd = TCellAgent::Cmdi.parse_command(@env, %w[echo argv0], :unsetenv_others => true)
50
+ expect(cmd).to eq('echo')
51
+ end
52
+ end
53
+
54
+ context 'with array command and arguments' do
55
+ it 'should parse the command properly' do
56
+ cmd = TCellAgent::Cmdi.parse_command(@env, %w[echo argv0], 'test', :unsetenv_others => true)
57
+ expect(cmd).to eq('echo test')
58
+
59
+ cmd = TCellAgent::Cmdi.parse_command(@env, %w[echo argv0], 'test', 'one', :unsetenv_others => true)
60
+ expect(cmd).to eq('echo test one')
61
+
62
+ cmd = TCellAgent::Cmdi.parse_command(
63
+ @env,
64
+ %w[magick argv0],
65
+ '-size',
66
+ '320x85',
67
+ 'canvas:none',
68
+ '-font',
69
+ 'Bookman-DemiItalic',
70
+ '-draw',
71
+ "\"text 25,60 \'Magick\'\"",
72
+ :unsetenv_others => true
73
+ )
74
+ expect(cmd).to eq(
75
+ "magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
76
+ )
77
+ end
78
+ end
79
+ end
80
+
81
+ context 'without env' do
82
+ context 'with string command' do
83
+ it 'should parse the command properly' do
84
+ cmd = TCellAgent::Cmdi.parse_command('echo')
85
+ expect(cmd).to eq('echo')
86
+
87
+ cmd = TCellAgent::Cmdi.parse_command('echo', :unsetenv_others => true)
88
+ expect(cmd).to eq('echo')
89
+ end
90
+ end
91
+
92
+ context 'with string command and arguments' do
93
+ it 'should parse the command' do
94
+ cmd = TCellAgent::Cmdi.parse_command('echo', 'test', :unsetenv_others => true)
95
+ expect(cmd).to eq('echo test')
96
+
97
+ cmd = TCellAgent::Cmdi.parse_command('echo', 'test', 'one', :unsetenv_others => true)
98
+ expect(cmd).to eq('echo test one')
99
+
100
+ cmd = TCellAgent::Cmdi.parse_command(
101
+ 'magick',
102
+ '-size',
103
+ '320x85',
104
+ 'canvas:none',
105
+ '-font',
106
+ 'Bookman-DemiItalic',
107
+ '-draw',
108
+ "\"text 25,60 \'Magick\'\"",
109
+ :unsetenv_others => true
110
+ )
111
+ expect(cmd).to eq(
112
+ "magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
113
+ )
114
+ end
115
+ end
116
+
117
+ context 'with array command' do
118
+ it 'should parse the command properly' do
119
+ cmd = TCellAgent::Cmdi.parse_command(%w[echo argv0], :unsetenv_others => true)
120
+ expect(cmd).to eq('echo')
121
+ end
122
+ end
123
+
124
+ context 'with array command and arguments' do
125
+ it 'should parse the command properly' do
126
+ cmd = TCellAgent::Cmdi.parse_command(%w[echo argv0], 'test', :unsetenv_others => true)
127
+ expect(cmd).to eq('echo test')
128
+
129
+ cmd = TCellAgent::Cmdi.parse_command(%w[echo argv0], 'test', 'one', :unsetenv_others => true)
130
+ expect(cmd).to eq('echo test one')
131
+
132
+ cmd = TCellAgent::Cmdi.parse_command(
133
+ %w[magick argv0],
134
+ '-size',
135
+ '320x85',
136
+ 'canvas:none',
137
+ '-font',
138
+ 'Bookman-DemiItalic',
139
+ '-draw',
140
+ "\"text 25,60 \'Magick\'\"",
141
+ :unsetenv_others => true
142
+ )
143
+ expect(cmd).to eq(
144
+ "magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
145
+ )
146
+ end
147
+ end
148
+ end
149
+ end
150
+ describe '.parse_command_from_open' do
151
+ context 'with empty parameters' do
152
+ it 'should not return a command' do
153
+ cmd = TCellAgent::Cmdi.parse_command_from_open
154
+ expect(cmd).to eq('')
155
+ end
156
+ end
157
+ context 'with empty array' do
158
+ it 'should not return a command' do
159
+ args = []
160
+ cmd = TCellAgent::Cmdi.parse_command_from_open(*args)
161
+ expect(cmd).to eq('')
162
+ end
163
+ end
164
+ context 'with a string command' do
165
+ context 'with an empty string' do
166
+ it 'should return an empty string' do
167
+ cmd = TCellAgent::Cmdi.parse_command_from_open('')
168
+ expect(cmd).to eq('')
169
+ end
170
+ end
171
+ context 'with an empty command' do
172
+ it 'should return an empty string' do
173
+ cmd = TCellAgent::Cmdi.parse_command_from_open('|')
174
+ expect(cmd).to eq('')
175
+ end
176
+ end
177
+ context 'with a non-empty command' do
178
+ it 'should parse the command properly' do
179
+ cmd = TCellAgent::Cmdi.parse_command_from_open('|echo')
180
+ expect(cmd).to eq('echo')
181
+
182
+ cmd = TCellAgent::Cmdi.parse_command_from_open('|ls -l /tmp')
183
+ expect(cmd).to eq('ls -l /tmp')
184
+ end
185
+ end
186
+ end
187
+ context 'with a filename argument' do
188
+ it 'should not return a command' do
189
+ cmd = TCellAgent::Cmdi.parse_command_from_open('/tmp')
190
+ expect(cmd).to eq('')
191
+ end
192
+ end
193
+ context 'with a non-string first argument' do
194
+ it 'should return an empty string' do
195
+ cmd = TCellAgent::Cmdi.parse_command_from_open({})
196
+ expect(cmd).to eq('')
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end