tcell_agent 0.2.29 → 0.4.0

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