tcell_agent 0.2.29 → 0.4.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 (100) hide show
  1. checksums.yaml +4 -4
  2. data/Readme.txt +7 -0
  3. data/bin/tcell_agent +9 -0
  4. data/lib/tcell_agent/agent/policy_manager.rb +3 -0
  5. data/lib/tcell_agent/agent/policy_types.rb +4 -1
  6. data/lib/tcell_agent/appsensor/injections_matcher.rb +20 -0
  7. data/lib/tcell_agent/appsensor/injections_reporter.rb +15 -56
  8. data/lib/tcell_agent/appsensor/meta_data.rb +56 -2
  9. data/lib/tcell_agent/appsensor/rules/baserules.json +371 -138
  10. data/lib/tcell_agent/cmdi.rb +113 -0
  11. data/lib/tcell_agent/config/unknown_options.rb +2 -0
  12. data/lib/tcell_agent/configuration.rb +30 -16
  13. data/lib/tcell_agent/hooks/login_fraud.rb +79 -0
  14. data/lib/tcell_agent/instrumentation.rb +6 -11
  15. data/lib/tcell_agent/patches/meta_data.rb +14 -11
  16. data/lib/tcell_agent/policies/appsensor/injection_sensor.rb +5 -9
  17. data/lib/tcell_agent/policies/appsensor_policy.rb +22 -206
  18. data/lib/tcell_agent/policies/clickjacking_policy.rb +4 -2
  19. data/lib/tcell_agent/policies/command_injection_policy.rb +196 -0
  20. data/lib/tcell_agent/policies/content_security_policy.rb +3 -2
  21. data/lib/tcell_agent/policies/dataloss_policy.rb +3 -1
  22. data/lib/tcell_agent/policies/honeytokens_policy.rb +3 -1
  23. data/lib/tcell_agent/policies/http_redirect_policy.rb +51 -37
  24. data/lib/tcell_agent/policies/http_tx_policy.rb +5 -1
  25. data/lib/tcell_agent/policies/login_fraud_policy.rb +6 -1
  26. data/lib/tcell_agent/policies/patches_policy.rb +3 -1
  27. data/lib/tcell_agent/policies/policy.rb +10 -0
  28. data/lib/tcell_agent/policies/secure_headers_policy.rb +5 -2
  29. data/lib/tcell_agent/rails/auth/devise.rb +12 -23
  30. data/lib/tcell_agent/rails/csrf_exception.rb +1 -1
  31. data/lib/tcell_agent/rails/dlp.rb +50 -54
  32. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +0 -1
  33. data/lib/tcell_agent/rails/middleware/context_middleware.rb +0 -1
  34. data/lib/tcell_agent/rails/middleware/global_middleware.rb +0 -1
  35. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +7 -10
  36. data/lib/tcell_agent/rails/on_start.rb +0 -1
  37. data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -4
  38. data/lib/tcell_agent/rails.rb +0 -2
  39. data/lib/tcell_agent/rust/libtcellagent-0.6.1.dylib +0 -0
  40. data/lib/tcell_agent/rust/libtcellagent-0.6.1.so +0 -0
  41. data/lib/tcell_agent/rust/models.rb +61 -0
  42. data/lib/tcell_agent/rust/tcellagent-0.6.1.dll +0 -0
  43. data/lib/tcell_agent/rust/whisperer.rb +112 -0
  44. data/lib/tcell_agent/sensor_events/appsensor_event.rb +25 -21
  45. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +31 -24
  46. data/lib/tcell_agent/sensor_events/command_injection.rb +58 -0
  47. data/lib/tcell_agent/sensor_events/discovery.rb +1 -1
  48. data/lib/tcell_agent/sensor_events/login_fraud.rb +3 -13
  49. data/lib/tcell_agent/sensor_events/sensor.rb +81 -77
  50. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +8 -0
  51. data/lib/tcell_agent/start_background_thread.rb +12 -3
  52. data/lib/tcell_agent/utils/io.rb +4 -1
  53. data/lib/tcell_agent/utils/params.rb +1 -0
  54. data/lib/tcell_agent/version.rb +1 -1
  55. data/lib/tcell_agent.rb +0 -1
  56. data/spec/lib/tcell_agent/appsensor/injections_matcher_spec.rb +27 -9
  57. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +143 -193
  58. data/spec/lib/tcell_agent/appsensor/meta_data_spec.rb +67 -0
  59. data/spec/lib/tcell_agent/appsensor/rules/appsensor_rule_manager_spec.rb +0 -10
  60. data/spec/lib/tcell_agent/cmdi_spec.rb +748 -0
  61. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +8 -0
  62. data/spec/lib/tcell_agent/configuration_spec.rb +138 -6
  63. data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +357 -0
  64. data/spec/lib/tcell_agent/patches/block_rule_spec.rb +70 -87
  65. data/spec/lib/tcell_agent/patches_spec.rb +9 -4
  66. data/spec/lib/tcell_agent/policies/appsensor/xss_sensor_spec.rb +186 -9
  67. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +309 -484
  68. data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +736 -0
  69. data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +222 -41
  70. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +56 -32
  71. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +161 -85
  72. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +40 -72
  73. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +267 -0
  74. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +20 -15
  75. data/spec/spec_helper.rb +0 -9
  76. data/tcell_agent.gemspec +8 -3
  77. metadata +40 -39
  78. data/lib/tcell_agent/appsensor/sensor.rb +0 -52
  79. data/lib/tcell_agent/policies/appsensor/database_sensor.rb +0 -56
  80. data/lib/tcell_agent/policies/appsensor/misc_sensor.rb +0 -59
  81. data/lib/tcell_agent/policies/appsensor/payloads_policy.rb +0 -150
  82. data/lib/tcell_agent/policies/appsensor/request_size_sensor.rb +0 -25
  83. data/lib/tcell_agent/policies/appsensor/response_codes_sensor.rb +0 -73
  84. data/lib/tcell_agent/policies/appsensor/response_size_sensor.rb +0 -25
  85. data/lib/tcell_agent/policies/appsensor/size_sensor.rb +0 -71
  86. data/lib/tcell_agent/policies/appsensor/user_agent_sensor.rb +0 -47
  87. data/lib/tcell_agent/rails/auth/hooks.rb +0 -79
  88. data/lib/tcell_agent/sensor_events/util/redirect_utils.rb +0 -22
  89. data/spec/lib/tcell_agent/policies/appsensor/database_sensor_spec.rb +0 -165
  90. data/spec/lib/tcell_agent/policies/appsensor/misc_sensor_spec.rb +0 -429
  91. data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_apply_spec.rb +0 -466
  92. data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_from_json_spec.rb +0 -890
  93. data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_log_spec.rb +0 -417
  94. data/spec/lib/tcell_agent/policies/appsensor/request_size_sensor_spec.rb +0 -236
  95. data/spec/lib/tcell_agent/policies/appsensor/response_codes_sensor_spec.rb +0 -297
  96. data/spec/lib/tcell_agent/policies/appsensor/response_size_sensor_spec.rb +0 -241
  97. data/spec/lib/tcell_agent/policies/appsensor/user_agent_sensor_spec.rb +0 -172
  98. data/spec/lib/tcell_agent/rails/auth/hooks_spec.rb +0 -246
  99. data/spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb +0 -25
  100. data/spec/support/resources/baserules.json +0 -155
@@ -0,0 +1,748 @@
1
+ require 'spec_helper'
2
+
3
+ module TCellAgent
4
+
5
+ module Cmdi
6
+ describe ".parse_command" do
7
+ context "with env" do
8
+ before(:each) do
9
+ @env = {"TCELL_VAR" => "enabled"}
10
+ end
11
+
12
+ context "with string command" do
13
+ it "should parse the command properly" do
14
+ cmd = TCellAgent::Cmdi.parse_command(@env, "echo")
15
+ expect(cmd).to eq("echo")
16
+
17
+ cmd = TCellAgent::Cmdi.parse_command(@env, "echo", :unsetenv_others => true)
18
+ expect(cmd).to eq("echo")
19
+ end
20
+ end
21
+
22
+ context "with string command and arguments" do
23
+ it "should parse the command" do
24
+ cmd = TCellAgent::Cmdi.parse_command(@env, "echo", "test", :unsetenv_others => true)
25
+ expect(cmd).to eq("echo test")
26
+
27
+ cmd = TCellAgent::Cmdi.parse_command(@env, "echo", "test", "one", :unsetenv_others => true)
28
+ expect(cmd).to eq("echo test one")
29
+
30
+ cmd = TCellAgent::Cmdi.parse_command(
31
+ @env,
32
+ "magick",
33
+ "-size",
34
+ "320x85",
35
+ "canvas:none",
36
+ "-font",
37
+ "Bookman-DemiItalic",
38
+ "-draw",
39
+ "\"text 25,60 \'Magick\'\"",
40
+ :unsetenv_others => true)
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, ["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, ["echo", "argv0"], "test", :unsetenv_others => true)
57
+ expect(cmd).to eq("echo test")
58
+
59
+ cmd = TCellAgent::Cmdi.parse_command(@env, ["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
+ ["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
+ expect(cmd).to eq(
74
+ "magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
75
+ )
76
+ end
77
+ end
78
+ end
79
+
80
+ context "without env" do
81
+ context "with string command" do
82
+ it "should parse the command properly" do
83
+ cmd = TCellAgent::Cmdi.parse_command("echo")
84
+ expect(cmd).to eq("echo")
85
+
86
+ cmd = TCellAgent::Cmdi.parse_command("echo", :unsetenv_others => true)
87
+ expect(cmd).to eq("echo")
88
+ end
89
+ end
90
+
91
+ context "with string command and arguments" do
92
+ it "should parse the command" do
93
+ cmd = TCellAgent::Cmdi.parse_command("echo", "test", :unsetenv_others => true)
94
+ expect(cmd).to eq("echo test")
95
+
96
+ cmd = TCellAgent::Cmdi.parse_command("echo", "test", "one", :unsetenv_others => true)
97
+ expect(cmd).to eq("echo test one")
98
+
99
+ cmd = TCellAgent::Cmdi.parse_command(
100
+ "magick",
101
+ "-size",
102
+ "320x85",
103
+ "canvas:none",
104
+ "-font",
105
+ "Bookman-DemiItalic",
106
+ "-draw",
107
+ "\"text 25,60 \'Magick\'\"",
108
+ :unsetenv_others => true)
109
+ expect(cmd).to eq(
110
+ "magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
111
+ )
112
+ end
113
+ end
114
+
115
+ context "with array command" do
116
+ it "should parse the command properly" do
117
+ cmd = TCellAgent::Cmdi.parse_command(["echo", "argv0"], :unsetenv_others => true)
118
+ expect(cmd).to eq("echo")
119
+ end
120
+ end
121
+
122
+ context "with array command and arguments" do
123
+ it "should parse the command properly" do
124
+ cmd = TCellAgent::Cmdi.parse_command(["echo", "argv0"], "test", :unsetenv_others => true)
125
+ expect(cmd).to eq("echo test")
126
+
127
+ cmd = TCellAgent::Cmdi.parse_command(["echo", "argv0"], "test", "one", :unsetenv_others => true)
128
+ expect(cmd).to eq("echo test one")
129
+
130
+ cmd = TCellAgent::Cmdi.parse_command(
131
+ ["magick", "argv0"],
132
+ "-size",
133
+ "320x85",
134
+ "canvas:none",
135
+ "-font",
136
+ "Bookman-DemiItalic",
137
+ "-draw",
138
+ "\"text 25,60 \'Magick\'\"",
139
+ :unsetenv_others => true)
140
+ expect(cmd).to eq(
141
+ "magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
142
+ )
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ describe IO do
150
+ describe ".popen" do
151
+ context "empty command" do
152
+ it "should raise an error" do
153
+ expect {
154
+ IO.popen()
155
+ }.to raise_error(ArgumentError)
156
+ expect {
157
+ IO.popen(nil)
158
+ }.to raise_error(TypeError)
159
+ expect {
160
+ IO.popen("")
161
+ }.to raise_error(Errno::ENOENT)
162
+ end
163
+ end
164
+
165
+ context "non existent command" do
166
+ it "should return nil" do
167
+ expect {
168
+ IO.popen("foobar")
169
+ }.to raise_error(Errno::ENOENT)
170
+ end
171
+ end
172
+
173
+ context "with a valid command" do
174
+ it "should execute command" do
175
+ expect(IO.popen("echo test").read.chomp).to eq("test")
176
+ end
177
+ end
178
+
179
+ context "with a non blocked command present" do
180
+ context "with no command injection" do
181
+ it "should execute the command" do
182
+ expect(TCellAgent).to receive(:policy).with(
183
+ TCellAgent::PolicyTypes::CommandInjection
184
+ ).and_return(nil)
185
+ expect_any_instance_of(TCellAgent::Policies::CommandInjectionPolicy).to_not receive(:enabled)
186
+ expect_any_instance_of(TCellAgent::Policies::CommandInjectionPolicy).to_not receive(:block?)
187
+
188
+ IO.popen("echo test")
189
+ end
190
+ end
191
+
192
+ context "with command injection disabled" do
193
+ it "should execute the command" do
194
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
195
+ expect(command_injection_policy.enabled).to eq(false)
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_call_original
201
+ expect(command_injection_policy).to_not receive(:block?)
202
+
203
+ IO.popen("echo test")
204
+ end
205
+ end
206
+
207
+ context "with command injection enabled" do
208
+ it "should execute the command" do
209
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
210
+ command_injection_policy.enabled = true
211
+ expect(command_injection_policy.enabled).to eq(true)
212
+
213
+ expect(TCellAgent).to receive(:policy).with(
214
+ TCellAgent::PolicyTypes::CommandInjection
215
+ ).and_return(command_injection_policy)
216
+ expect(command_injection_policy).to receive(:enabled).and_call_original
217
+ expect(command_injection_policy).to receive(:block?).with("echo test", nil).and_return(false)
218
+
219
+ IO.popen("echo test")
220
+ end
221
+ end
222
+ end
223
+
224
+ context "with a blocked command present" do
225
+ context "with command injection enabled" do
226
+ it "should raise a Errno::ENOENT" do
227
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
228
+ command_injection_policy.enabled = true
229
+ expect(command_injection_policy.enabled).to eq(true)
230
+
231
+ expect(TCellAgent).to receive(:policy).with(
232
+ TCellAgent::PolicyTypes::CommandInjection
233
+ ).and_return(command_injection_policy)
234
+ expect(command_injection_policy).to receive(:enabled).and_call_original
235
+ expect(command_injection_policy).to receive(:block?).with("echo test", nil).and_return(true)
236
+
237
+ expect {
238
+ IO.popen("echo test")
239
+ }.to raise_error(Errno::ENOENT)
240
+ end
241
+ end
242
+ end
243
+
244
+ context "with env" do
245
+ before(:each) do
246
+ @env = {"TCELL_VAR" => "enabled"}
247
+ end
248
+
249
+ context "with string command" do
250
+ it "should execute the command" do
251
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo")
252
+ IO.popen(@env, "echo", "w+")
253
+
254
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo")
255
+ IO.popen(@env, "echo", "w+", :unsetenv_others => true)
256
+ end
257
+ end
258
+
259
+ context "with string command and arguments" do
260
+ it "should parse the command" do
261
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
262
+ IO.popen(@env, "echo test")
263
+
264
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
265
+ IO.popen(@env, "echo test", "w+")
266
+
267
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
268
+ IO.popen(@env, "echo test", :unsetenv_others => true)
269
+
270
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
271
+ IO.popen(@env, "echo test", "w+", :unsetenv_others => true)
272
+ end
273
+ end
274
+
275
+ context "with array command" do
276
+ it "should parse the command properly" do
277
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo")
278
+ IO.popen(@env, [["echo", "argv0"]], "w+")
279
+
280
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo")
281
+ IO.popen(@env, [["echo", "argv0"]], :unsetenv_others => true)
282
+
283
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo")
284
+ IO.popen(@env, [["echo", "argv0"]], "w+", :unsetenv_others => true)
285
+
286
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo")
287
+ IO.popen(@env, ["echo"], "w+")
288
+
289
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo")
290
+ IO.popen(@env, ["echo"], :unsetenv_others => true)
291
+
292
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo")
293
+ IO.popen(@env, ["echo"], "w+", :unsetenv_others => true)
294
+ end
295
+ end
296
+
297
+ context "with array command and arguments" do
298
+ it "should parse the command properly" do
299
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
300
+ IO.popen(@env, [["echo", "argv0"], "test"])
301
+
302
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
303
+ IO.popen(@env, [["echo", "argv0"], "test"], "w+")
304
+
305
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
306
+ IO.popen(@env, [["echo", "argv0"], "test"], :unsetenv_others => true)
307
+
308
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
309
+ IO.popen(@env, [["echo", "argv0"], "test"], "w+", :unsetenv_others => true)
310
+
311
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
312
+ IO.popen(@env, ["echo", "test"])
313
+
314
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
315
+ IO.popen(@env, ["echo", "test"], "w+")
316
+
317
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
318
+ IO.popen(@env, ["echo", "test"], :unsetenv_others => true)
319
+
320
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
321
+ IO.popen(@env, ["echo", "test"], "w+", :unsetenv_others => true)
322
+
323
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
324
+ IO.popen([@env, "echo", "test", :unsetenv_others => true], "w+")
325
+
326
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
327
+ IO.popen(@env, [@env, "echo", "test", :unsetenv_others => true], "w+", :err=>[:child, :out])
328
+ end
329
+ end
330
+ end
331
+
332
+ context "without env" do
333
+ context "with array command and arguments" do
334
+ it "should parse the command properly" do
335
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
336
+ IO.popen([["echo", "argv0"], "test"])
337
+
338
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
339
+ IO.popen([["echo", "argv0"], "test"], "w+")
340
+
341
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
342
+ IO.popen([["echo", "argv0"], "test"], :unsetenv_others => true)
343
+
344
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
345
+ IO.popen([["echo", "argv0"], "test"], "w+", :unsetenv_others => true)
346
+
347
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
348
+ IO.popen(["echo", "test"])
349
+
350
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
351
+ IO.popen(["echo", "test"], "w+")
352
+
353
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
354
+ IO.popen(["echo", "test"], :unsetenv_others => true)
355
+
356
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with("echo test")
357
+ IO.popen(["echo", "test"], "w+", :unsetenv_others => true)
358
+
359
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with(
360
+ "echo -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
361
+ )
362
+ IO.popen(
363
+ [["echo", "argv0"],
364
+ "-size",
365
+ "320x85",
366
+ "canvas:none",
367
+ "-font",
368
+ "Bookman-DemiItalic",
369
+ "-draw",
370
+ "\"text 25,60 \'Magick\'\""],
371
+ :unsetenv_others => true)
372
+ end
373
+ end
374
+ end
375
+ end
376
+ end
377
+
378
+ describe Kernel do
379
+
380
+ describe ".backtick" do
381
+ context "empty command" do
382
+ it "should raise Errno::ENOENT" do
383
+ expect {
384
+ ``
385
+ }.to raise_error(Errno::ENOENT)
386
+ end
387
+ end
388
+
389
+ context "with a non blocked command present" do
390
+ context "with no command injection" do
391
+ it "should execute the command" do
392
+ expect(TCellAgent).to receive(:policy).with(
393
+ TCellAgent::PolicyTypes::CommandInjection
394
+ ).and_return(nil)
395
+ expect_any_instance_of(TCellAgent::Policies::CommandInjectionPolicy).to_not receive(:enabled)
396
+ expect_any_instance_of(TCellAgent::Policies::CommandInjectionPolicy).to_not receive(:block?)
397
+
398
+ `echo test`
399
+ end
400
+ end
401
+
402
+ context "with command injection disabled" do
403
+ it "should execute the command" do
404
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
405
+ expect(command_injection_policy.enabled).to eq(false)
406
+
407
+ expect(TCellAgent).to receive(:policy).with(
408
+ TCellAgent::PolicyTypes::CommandInjection
409
+ ).and_return(command_injection_policy)
410
+ expect(command_injection_policy).to receive(:enabled).and_call_original
411
+ expect(command_injection_policy).to_not receive(:block?)
412
+
413
+ `echo test`
414
+ end
415
+ end
416
+
417
+ context "with command injection enabled" do
418
+ it "should execute the command" do
419
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
420
+ command_injection_policy.enabled = true
421
+ expect(command_injection_policy.enabled).to eq(true)
422
+
423
+ expect(TCellAgent).to receive(:policy).with(
424
+ TCellAgent::PolicyTypes::CommandInjection
425
+ ).and_return(command_injection_policy)
426
+ expect(command_injection_policy).to receive(:enabled).and_call_original
427
+ expect(command_injection_policy).to receive(:block?).with("echo test", nil).and_return(false)
428
+
429
+ `echo test`
430
+ end
431
+ end
432
+ end
433
+
434
+ context "with a blocked command present" do
435
+ context "with command injection enabled" do
436
+ it "should raise a Errno::ENOENT" do
437
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
438
+ command_injection_policy.enabled = true
439
+ expect(command_injection_policy.enabled).to eq(true)
440
+
441
+ expect(TCellAgent).to receive(:policy).with(
442
+ TCellAgent::PolicyTypes::CommandInjection
443
+ ).and_return(command_injection_policy)
444
+ expect(command_injection_policy).to receive(:enabled).and_call_original
445
+ expect(command_injection_policy).to receive(:block?).with("echo test", nil).and_return(true)
446
+
447
+ expect {
448
+ `echo test`
449
+ }.to raise_error(Errno::ENOENT)
450
+ end
451
+ end
452
+ end
453
+ end
454
+
455
+ describe "%x methods" do
456
+ context "empty command" do
457
+ it "should raise Errno::ENOENT" do
458
+ expect {
459
+ %x{}
460
+ }.to raise_error(Errno::ENOENT)
461
+ end
462
+ end
463
+
464
+ context "with a non blocked command present" do
465
+ context "with no command injection" do
466
+ it "should execute the command" do
467
+ expect(TCellAgent).to receive(:policy).with(
468
+ TCellAgent::PolicyTypes::CommandInjection
469
+ ).and_return(nil)
470
+ expect_any_instance_of(TCellAgent::Policies::CommandInjectionPolicy).to_not receive(:enabled)
471
+ expect_any_instance_of(TCellAgent::Policies::CommandInjectionPolicy).to_not receive(:block?)
472
+
473
+ %x{echo test}
474
+ end
475
+ end
476
+
477
+ context "with command injection disabled" do
478
+ it "should execute the command" do
479
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
480
+ expect(command_injection_policy.enabled).to eq(false)
481
+
482
+ expect(TCellAgent).to receive(:policy).with(
483
+ TCellAgent::PolicyTypes::CommandInjection
484
+ ).and_return(command_injection_policy)
485
+ expect(command_injection_policy).to receive(:enabled).and_call_original
486
+ expect(command_injection_policy).to_not receive(:block?)
487
+
488
+ %x{echo test}
489
+ end
490
+ end
491
+
492
+ context "with command injection enabled" do
493
+ it "should execute the command" do
494
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
495
+ command_injection_policy.enabled = true
496
+ expect(command_injection_policy.enabled).to eq(true)
497
+
498
+ expect(TCellAgent).to receive(:policy).with(
499
+ TCellAgent::PolicyTypes::CommandInjection
500
+ ).and_return(command_injection_policy)
501
+ expect(command_injection_policy).to receive(:enabled).and_call_original
502
+ expect(command_injection_policy).to receive(:block?).with("echo test", nil).and_return(false)
503
+
504
+ %x{echo test}
505
+ end
506
+ end
507
+ end
508
+
509
+ context "with a blocked command present" do
510
+ context "with command injection enabled" do
511
+ it "should raise a Errno::ENOENT" do
512
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
513
+ command_injection_policy.enabled = true
514
+ expect(command_injection_policy.enabled).to eq(true)
515
+
516
+ expect(TCellAgent).to receive(:policy).with(
517
+ TCellAgent::PolicyTypes::CommandInjection
518
+ ).and_return(command_injection_policy)
519
+ expect(command_injection_policy).to receive(:enabled).and_call_original
520
+ expect(command_injection_policy).to receive(:block?).with("echo test", nil).and_return(true)
521
+
522
+ expect {
523
+ %x{echo test}
524
+ }.to raise_error(Errno::ENOENT)
525
+ end
526
+ end
527
+ end
528
+ end
529
+
530
+ describe ".system" do
531
+ context "empty command" do
532
+ it "should raise an error" do
533
+ expect {
534
+ system()
535
+ }.to raise_error(ArgumentError)
536
+ expect {
537
+ system(nil)
538
+ }.to raise_error(TypeError)
539
+
540
+ expect(system("")).to be_nil
541
+ end
542
+ end
543
+
544
+ context "non existent command" do
545
+ it "should return nil" do
546
+ expect(system("foobar")).to be_nil
547
+ end
548
+ end
549
+
550
+ context "with a valid command" do
551
+ it "should execute command" do
552
+ pid = system("echo test > /dev/null 2>&1")
553
+ expect(pid).to eq(true)
554
+
555
+ pid = system(RbConfig.ruby, "-e'Hello World!'", ">", "/dev/null", "2>&1")
556
+ expect(pid).to eq(true)
557
+ end
558
+ end
559
+
560
+ context "with a non blocked command present" do
561
+ context "with no command injection" do
562
+ it "should execute the command" do
563
+ expect(TCellAgent).to receive(:policy).with(
564
+ TCellAgent::PolicyTypes::CommandInjection
565
+ ).and_return(nil)
566
+ expect_any_instance_of(TCellAgent::Policies::CommandInjectionPolicy).to_not receive(:enabled)
567
+ expect_any_instance_of(TCellAgent::Policies::CommandInjectionPolicy).to_not receive(:block?)
568
+
569
+ system("echo test > /dev/null 2>&1")
570
+ end
571
+ end
572
+
573
+ context "with command injection disabled" do
574
+ it "should execute the command" do
575
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
576
+ expect(command_injection_policy.enabled).to eq(false)
577
+
578
+ expect(TCellAgent).to receive(:policy).with(
579
+ TCellAgent::PolicyTypes::CommandInjection
580
+ ).and_return(command_injection_policy)
581
+ expect(command_injection_policy).to receive(:enabled).and_call_original
582
+ expect(command_injection_policy).to_not receive(:block?)
583
+
584
+ system("echo test > /dev/null 2>&1")
585
+ end
586
+ end
587
+
588
+ context "with command injection enabled" do
589
+ it "should execute the command" do
590
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
591
+ command_injection_policy.enabled = true
592
+ expect(command_injection_policy.enabled).to eq(true)
593
+
594
+ expect(TCellAgent).to receive(:policy).with(
595
+ TCellAgent::PolicyTypes::CommandInjection
596
+ ).and_return(command_injection_policy)
597
+ expect(command_injection_policy).to receive(:enabled).and_call_original
598
+ expect(command_injection_policy).to receive(:block?).with("echo test > /dev/null 2>&1", nil).and_return(false)
599
+
600
+ system("echo test > /dev/null 2>&1")
601
+ end
602
+ end
603
+ end
604
+
605
+ context "with a blocked command present" do
606
+ context "with command injection enabled" do
607
+ it "should raise a Errno::ENOENT" do
608
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
609
+ command_injection_policy.enabled = true
610
+ expect(command_injection_policy.enabled).to eq(true)
611
+
612
+ expect(TCellAgent).to receive(:policy).with(
613
+ TCellAgent::PolicyTypes::CommandInjection
614
+ ).and_return(command_injection_policy)
615
+ expect(command_injection_policy).to receive(:enabled).and_call_original
616
+ expect(command_injection_policy).to receive(:block?).with("echo test", nil).and_return(true)
617
+
618
+ expect {
619
+ system("echo test")
620
+ }.to raise_error(Errno::ENOENT)
621
+ end
622
+ end
623
+ end
624
+ end
625
+
626
+ describe ".spawn" do
627
+ context "empty command" do
628
+ it "should raise an error" do
629
+ expect {
630
+ spawn()
631
+ }.to raise_error(ArgumentError)
632
+ expect {
633
+ spawn(nil)
634
+ }.to raise_error(TypeError)
635
+ expect {
636
+ spawn("")
637
+ }.to raise_error(Errno::ENOENT)
638
+ end
639
+ end
640
+
641
+ context "non existent command" do
642
+ it "should raise error" do
643
+ expect {
644
+ spawn("foobar")
645
+ }.to raise_error(Errno::ENOENT)
646
+ end
647
+ end
648
+
649
+ context "with a valid command" do
650
+ it "should execute command" do
651
+ pid = spawn("echo test > /dev/null 2>&1")
652
+ expect(pid).to_not be_nil
653
+
654
+ pid = spawn(RbConfig.ruby, "-e'Hello World!'", ">", "/dev/null", "2>&1")
655
+ expect(pid).to_not be_nil
656
+ end
657
+ end
658
+
659
+ context "with a non blocked command present" do
660
+ context "with no command injection" do
661
+ it "should execute the command" do
662
+ expect(TCellAgent).to receive(:policy).with(
663
+ TCellAgent::PolicyTypes::CommandInjection
664
+ ).and_return(nil)
665
+ expect_any_instance_of(TCellAgent::Policies::CommandInjectionPolicy).to_not receive(:enabled)
666
+ expect_any_instance_of(TCellAgent::Policies::CommandInjectionPolicy).to_not receive(:block?)
667
+
668
+ spawn("echo test > /dev/null 2>&1")
669
+ end
670
+ end
671
+
672
+ context "with command injection disabled" do
673
+ it "should execute the command" do
674
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
675
+ expect(command_injection_policy.enabled).to eq(false)
676
+
677
+ expect(TCellAgent).to receive(:policy).with(
678
+ TCellAgent::PolicyTypes::CommandInjection
679
+ ).and_return(command_injection_policy)
680
+ expect(command_injection_policy).to receive(:enabled).and_call_original
681
+ expect(command_injection_policy).to_not receive(:block?)
682
+
683
+ spawn("echo test > /dev/null 2>&1")
684
+ end
685
+ end
686
+
687
+ context "with command injection enabled" do
688
+ it "should execute the command" do
689
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
690
+ command_injection_policy.enabled = true
691
+ expect(command_injection_policy.enabled).to eq(true)
692
+
693
+ expect(TCellAgent).to receive(:policy).with(
694
+ TCellAgent::PolicyTypes::CommandInjection
695
+ ).and_return(command_injection_policy)
696
+ expect(command_injection_policy).to receive(:enabled).and_call_original
697
+ expect(command_injection_policy).to receive(:block?).with("echo test > /dev/null 2>&1", nil).and_return(false)
698
+
699
+ spawn("echo test > /dev/null 2>&1")
700
+ end
701
+ end
702
+ end
703
+
704
+ context "with a blocked command present" do
705
+ context "with command injection enabled" do
706
+ it "should raise a Errno::ENOENT" do
707
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
708
+ command_injection_policy.enabled = true
709
+ expect(command_injection_policy.enabled).to eq(true)
710
+
711
+ expect(TCellAgent).to receive(:policy).with(
712
+ TCellAgent::PolicyTypes::CommandInjection
713
+ ).and_return(command_injection_policy)
714
+ expect(command_injection_policy).to receive(:enabled).and_call_original
715
+ expect(command_injection_policy).to receive(:block?).with("echo test", nil).and_return(true)
716
+
717
+ expect {
718
+ spawn("echo test")
719
+ }.to raise_error(Errno::ENOENT)
720
+ end
721
+ end
722
+ end
723
+ end
724
+
725
+ describe ".exec" do
726
+ # can only test this case since exec replaces current process with new process
727
+ context "with a blocked command present" do
728
+ context "with command injection enabled" do
729
+ it "should raise a Errno::ENOENT" do
730
+ command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new
731
+ command_injection_policy.enabled = true
732
+ expect(command_injection_policy.enabled).to eq(true)
733
+
734
+ expect(TCellAgent).to receive(:policy).with(
735
+ TCellAgent::PolicyTypes::CommandInjection
736
+ ).and_return(command_injection_policy)
737
+ expect(command_injection_policy).to receive(:enabled).and_call_original
738
+ expect(command_injection_policy).to receive(:block?).with("echo test", nil).and_return(true)
739
+
740
+ expect {
741
+ exec("echo test")
742
+ }.to raise_error(Errno::ENOENT)
743
+ end
744
+ end
745
+ end
746
+ end
747
+ end
748
+ end