tcell_agent 1.1.12 → 2.2.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 (169) hide show
  1. checksums.yaml +5 -5
  2. data/bin/tcell_agent +45 -137
  3. data/lib/tcell_agent.rb +12 -14
  4. data/lib/tcell_agent/agent.rb +108 -97
  5. data/lib/tcell_agent/agent/route_manager.rb +0 -16
  6. data/lib/tcell_agent/agent/static_agent.rb +9 -30
  7. data/lib/tcell_agent/config_initializer.rb +66 -0
  8. data/lib/tcell_agent/configuration.rb +69 -345
  9. data/lib/tcell_agent/hooks/login_fraud.rb +30 -33
  10. data/lib/tcell_agent/instrument_servers.rb +23 -0
  11. data/lib/tcell_agent/instrumentation.rb +12 -10
  12. data/lib/tcell_agent/instrumentation/cmdi.rb +29 -25
  13. data/lib/tcell_agent/instrumentation/lfi.rb +84 -0
  14. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +25 -0
  15. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +131 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +102 -0
  17. data/lib/tcell_agent/logger.rb +49 -114
  18. data/lib/tcell_agent/patches.rb +6 -7
  19. data/lib/tcell_agent/policies/appfirewall_policy.rb +26 -0
  20. data/lib/tcell_agent/policies/command_injection_policy.rb +28 -0
  21. data/lib/tcell_agent/policies/dataloss_policy.rb +44 -44
  22. data/lib/tcell_agent/policies/headers_policy.rb +25 -0
  23. data/lib/tcell_agent/policies/http_redirect_policy.rb +13 -79
  24. data/lib/tcell_agent/policies/js_agent_policy.rb +27 -0
  25. data/lib/tcell_agent/policies/local_file_access.rb +28 -0
  26. data/lib/tcell_agent/policies/login_policy.rb +43 -0
  27. data/lib/tcell_agent/policies/patches_policy.rb +27 -0
  28. data/lib/tcell_agent/policies/policies_manager.rb +68 -0
  29. data/lib/tcell_agent/policies/policy_polling.rb +58 -0
  30. data/lib/tcell_agent/policies/policy_types.rb +14 -0
  31. data/lib/tcell_agent/policies/system_enablements.rb +27 -0
  32. data/lib/tcell_agent/rails/auth/authlogic.rb +46 -75
  33. data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
  34. data/lib/tcell_agent/rails/auth/devise.rb +100 -105
  35. data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
  36. data/lib/tcell_agent/rails/auth/doorkeeper.rb +62 -76
  37. data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
  38. data/lib/tcell_agent/rails/csrf_exception.rb +2 -10
  39. data/lib/tcell_agent/rails/dlp.rb +35 -23
  40. data/lib/tcell_agent/rails/dlp_handler.rb +1 -2
  41. data/lib/tcell_agent/rails/js_agent_insert.rb +12 -13
  42. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +4 -25
  43. data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -12
  44. data/lib/tcell_agent/rails/middleware/global_middleware.rb +1 -2
  45. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +14 -34
  46. data/lib/tcell_agent/{rails.rb → rails/railties/tcell_agent_railties.rb} +11 -16
  47. data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
  48. data/lib/tcell_agent/rails/routes.rb +10 -12
  49. data/lib/tcell_agent/rails/routes/grape.rb +4 -14
  50. data/lib/tcell_agent/rails/routes/route_id.rb +3 -1
  51. data/lib/tcell_agent/rails/settings_reporter.rb +23 -36
  52. data/lib/tcell_agent/rails/tcell_body_proxy.rb +5 -4
  53. data/lib/tcell_agent/rust/agent_config.rb +60 -0
  54. data/lib/tcell_agent/rust/{libtcellagent-alpine-1.3.2.so → libtcellagent-5.0.2.dylib} +0 -0
  55. data/lib/tcell_agent/rust/{libtcellagent-1.3.2.so → libtcellagent-5.0.2.so} +0 -0
  56. data/lib/tcell_agent/rust/libtcellagent-alpine-5.0.2.so +0 -0
  57. data/lib/tcell_agent/rust/models.rb +6 -52
  58. data/lib/tcell_agent/rust/native_agent.rb +549 -0
  59. data/lib/tcell_agent/rust/native_agent_response.rb +42 -0
  60. data/lib/tcell_agent/rust/native_library.rb +69 -0
  61. data/lib/tcell_agent/rust/tcellagent-5.0.2.dll +0 -0
  62. data/lib/tcell_agent/sensor_events/agent_setting_event.rb +12 -0
  63. data/lib/tcell_agent/sensor_events/{app_config.rb → app_config_setting_event.rb} +0 -6
  64. data/lib/tcell_agent/sensor_events/dlp.rb +2 -6
  65. data/lib/tcell_agent/sensor_events/sensor.rb +0 -62
  66. data/lib/tcell_agent/sensor_events/server_agent.rb +13 -18
  67. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +0 -108
  68. data/lib/tcell_agent/sensor_events/util/utils.rb +0 -2
  69. data/lib/tcell_agent/servers/passenger.rb +1 -28
  70. data/lib/tcell_agent/servers/puma.rb +3 -21
  71. data/lib/tcell_agent/servers/rails_server.rb +1 -2
  72. data/lib/tcell_agent/servers/thin.rb +2 -2
  73. data/lib/tcell_agent/servers/unicorn.rb +19 -80
  74. data/lib/tcell_agent/servers/webrick.rb +1 -2
  75. data/lib/tcell_agent/settings_reporter.rb +11 -90
  76. data/lib/tcell_agent/sinatra.rb +14 -16
  77. data/lib/tcell_agent/tcell_context.rb +40 -14
  78. data/lib/tcell_agent/utils/headers.rb +14 -0
  79. data/lib/tcell_agent/version.rb +1 -1
  80. data/spec/lib/tcell_agent/configuration_spec.rb +55 -346
  81. data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +46 -173
  82. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +504 -0
  83. data/spec/lib/tcell_agent/instrumentation/cmdi/kernel_cmdi_spec.rb +435 -0
  84. data/spec/lib/tcell_agent/instrumentation/cmdi_spec.rb +201 -0
  85. data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +326 -0
  86. data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +562 -0
  87. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +264 -0
  88. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +150 -0
  89. data/spec/lib/tcell_agent/patches_spec.rb +25 -43
  90. data/spec/lib/tcell_agent/policies/appfirewall_policy_spec.rb +183 -0
  91. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +57 -0
  92. data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +84 -773
  93. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +161 -0
  94. data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +9 -9
  95. data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +243 -198
  96. data/spec/lib/tcell_agent/policies/js_agent_policy_spec.rb +75 -0
  97. data/spec/lib/tcell_agent/policies/login_policy_spec.rb +165 -33
  98. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +84 -277
  99. data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +104 -0
  100. data/spec/lib/tcell_agent/policies/policy_polling_spec.rb +6 -0
  101. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +56 -0
  102. data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +9 -18
  103. data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +13 -30
  104. data/spec/lib/tcell_agent/rails/logger_spec.rb +27 -7
  105. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +17 -12
  106. data/spec/lib/tcell_agent/rails/routes/routes_spec.rb +14 -14
  107. data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
  108. data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +0 -35
  109. data/spec/lib/tcell_agent/settings_reporter_spec.rb +56 -155
  110. data/spec/spec_helper.rb +1 -1
  111. data/spec/support/builders.rb +103 -0
  112. data/spec/support/force_logger_mocking.rb +38 -0
  113. data/spec/support/resources/lfi_sample_file.txt +2 -0
  114. data/spec/support/static_agent_overrides.rb +0 -15
  115. metadata +72 -83
  116. data/lib/tcell_agent/agent/event_processor.rb +0 -326
  117. data/lib/tcell_agent/agent/fork_pipe_manager.rb +0 -113
  118. data/lib/tcell_agent/agent/policy_manager.rb +0 -219
  119. data/lib/tcell_agent/agent/policy_types.rb +0 -30
  120. data/lib/tcell_agent/api.rb +0 -91
  121. data/lib/tcell_agent/appsensor/injections_reporter.rb +0 -24
  122. data/lib/tcell_agent/authlogic.rb +0 -26
  123. data/lib/tcell_agent/config/child_process_events.rb +0 -8
  124. data/lib/tcell_agent/config/unknown_options.rb +0 -123
  125. data/lib/tcell_agent/devise.rb +0 -35
  126. data/lib/tcell_agent/instrumentation/cmdi/backtick.rb +0 -10
  127. data/lib/tcell_agent/instrumentation/cmdi/exec.rb +0 -14
  128. data/lib/tcell_agent/instrumentation/cmdi/popen.rb +0 -28
  129. data/lib/tcell_agent/instrumentation/cmdi/spawn.rb +0 -11
  130. data/lib/tcell_agent/instrumentation/cmdi/system.rb +0 -11
  131. data/lib/tcell_agent/policies/http_tx_policy.rb +0 -60
  132. data/lib/tcell_agent/policies/login_fraud_policy.rb +0 -45
  133. data/lib/tcell_agent/policies/rust_policies.rb +0 -110
  134. data/lib/tcell_agent/rails/on_start.rb +0 -41
  135. data/lib/tcell_agent/rust/libtcellagent-1.3.2.dylib +0 -0
  136. data/lib/tcell_agent/rust/tcellagent-1.3.2.dll +0 -0
  137. data/lib/tcell_agent/rust/whisperer.rb +0 -308
  138. data/lib/tcell_agent/sensor_events/appsensor_event.rb +0 -52
  139. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +0 -45
  140. data/lib/tcell_agent/sensor_events/command_injection.rb +0 -75
  141. data/lib/tcell_agent/sensor_events/honeytokens.rb +0 -16
  142. data/lib/tcell_agent/sensor_events/login_fraud.rb +0 -60
  143. data/lib/tcell_agent/sensor_events/metrics.rb +0 -123
  144. data/lib/tcell_agent/sensor_events/patches.rb +0 -21
  145. data/lib/tcell_agent/start_background_thread.rb +0 -55
  146. data/lib/tcell_agent/system_info.rb +0 -11
  147. data/lib/tcell_agent/utils/io.rb +0 -38
  148. data/lib/tcell_agent/utils/passwords.rb +0 -28
  149. data/lib/tcell_agent/utils/queue_with_timeout.rb +0 -142
  150. data/spec/lib/tcell_agent/agent/fork_pipe_manager_spec.rb +0 -100
  151. data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +0 -535
  152. data/spec/lib/tcell_agent/agent/static_agent_spec.rb +0 -133
  153. data/spec/lib/tcell_agent/api/api_spec.rb +0 -39
  154. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +0 -187
  155. data/spec/lib/tcell_agent/cmdi_spec.rb +0 -736
  156. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -213
  157. data/spec/lib/tcell_agent/instrumentation_spec.rb +0 -225
  158. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +0 -517
  159. data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +0 -22
  160. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +0 -293
  161. data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +0 -198
  162. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +0 -180
  163. data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +0 -116
  164. data/spec/lib/tcell_agent/rust/models_spec.rb +0 -120
  165. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +0 -704
  166. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +0 -45
  167. data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +0 -272
  168. data/spec/lib/tcell_agent/utils/bounded_queue_spec.rb +0 -52
  169. data/spec/lib/tcell_agent/utils/passwords_spec.rb +0 -143
@@ -0,0 +1,504 @@
1
+ require 'spec_helper'
2
+
3
+ describe IO do
4
+ describe '.binread' do
5
+ before(:each) do
6
+ native_agent = double('native_agent')
7
+ @command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new(
8
+ native_agent, {}
9
+ )
10
+ end
11
+ context 'empty name' do
12
+ it 'should raise an error' do
13
+ expect do
14
+ IO.binread
15
+ end.to raise_error(ArgumentError)
16
+ expect do
17
+ IO.binread(nil)
18
+ end.to raise_error(TypeError)
19
+ expect do
20
+ IO.binread('')
21
+ end.to raise_error(Errno::ENOENT)
22
+ end
23
+ end
24
+ context 'name starts with a | operator' do
25
+ context 'with an empty or invalid command' do
26
+ it 'should raise an error' do
27
+ expect do
28
+ IO.binread('|')
29
+ end.to raise_error(Errno::ENOENT)
30
+
31
+ expect do
32
+ IO.binread('|invalid command')
33
+ end.to raise_error(Errno::ENOENT)
34
+
35
+ expect do
36
+ IO.binread('|invalid command', 10)
37
+ end.to raise_error(Errno::ENOENT)
38
+
39
+ expect do
40
+ IO.binread('|invalid command', 10, 20)
41
+ end.to raise_error(Errno::ENOENT)
42
+ end
43
+ end
44
+ context 'with a valid command' do
45
+ it 'should execute the command' do
46
+ expect(IO.binread('|echo test')).to eq("test\n")
47
+ end
48
+ end
49
+ context 'with a non blocked command present' do
50
+ before(:each) do
51
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
52
+ end
53
+ context 'with command injection disabled' do
54
+ it 'should execute the command' do
55
+ expect(@command_injection_policy.enabled).to eq(false)
56
+
57
+ expect(TCellAgent).to receive(:policy).with(
58
+ TCellAgent::PolicyTypes::COMMANDINJECTION
59
+ ).and_return(@command_injection_policy)
60
+ expect(@command_injection_policy).to receive(:enabled).and_call_original
61
+ expect(@command_injection_policy).to_not receive(:block_command?)
62
+
63
+ expect(IO.binread('|echo test')).to eq("test\n")
64
+ end
65
+ end
66
+
67
+ context 'with command injection enabled' do
68
+ it 'should execute the command' do
69
+ expect(TCellAgent).to receive(:policy).with(
70
+ TCellAgent::PolicyTypes::COMMANDINJECTION
71
+ ).and_return(@command_injection_policy)
72
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
73
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(false)
74
+
75
+ expect(IO.binread('|echo test')).to eq("test\n")
76
+ end
77
+ end
78
+ end
79
+
80
+ context 'with a blocked command present' do
81
+ context 'with command injection enabled' do
82
+ it 'should raise a RuntimeError' do
83
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
84
+
85
+ expect(TCellAgent).to receive(:policy).with(
86
+ TCellAgent::PolicyTypes::COMMANDINJECTION
87
+ ).and_return(@command_injection_policy)
88
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
89
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(true)
90
+
91
+ expect do
92
+ IO.binread('|echo test')
93
+ end.to raise_error(RuntimeError)
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ describe '.popen' do
100
+ before(:each) do
101
+ native_agent = double('native_agent')
102
+ @command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new(
103
+ native_agent, {}
104
+ )
105
+ end
106
+
107
+ context 'empty command' do
108
+ it 'should raise an error' do
109
+ expect do
110
+ IO.popen
111
+ end.to raise_error(ArgumentError)
112
+ expect do
113
+ IO.popen(nil)
114
+ end.to raise_error(TypeError)
115
+ expect do
116
+ IO.popen('')
117
+ end.to raise_error(Errno::ENOENT)
118
+ end
119
+ end
120
+
121
+ context 'non existent command' do
122
+ it 'should return nil' do
123
+ expect do
124
+ IO.popen('foobar')
125
+ end.to raise_error(Errno::ENOENT)
126
+ end
127
+ end
128
+
129
+ context 'with a valid command' do
130
+ it 'should execute command' do
131
+ expect(IO.popen('echo test').read).to eq("test\n")
132
+ end
133
+ end
134
+
135
+ context 'with a non blocked command present' do
136
+ before(:each) do
137
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
138
+ end
139
+
140
+ context 'with command injection disabled' do
141
+ it 'should execute the command' do
142
+ expect(@command_injection_policy.enabled).to eq(false)
143
+
144
+ expect(TCellAgent).to receive(:policy).with(
145
+ TCellAgent::PolicyTypes::COMMANDINJECTION
146
+ ).and_return(@command_injection_policy)
147
+ expect(@command_injection_policy).to receive(:enabled).and_call_original
148
+ expect(@command_injection_policy).to_not receive(:block_command?)
149
+
150
+ IO.popen('echo test')
151
+ end
152
+ end
153
+
154
+ context 'with command injection enabled' do
155
+ it 'should execute the command' do
156
+ expect(TCellAgent).to receive(:policy).with(
157
+ TCellAgent::PolicyTypes::COMMANDINJECTION
158
+ ).and_return(@command_injection_policy)
159
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
160
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(false)
161
+
162
+ IO.popen('echo test')
163
+ end
164
+ end
165
+ end
166
+
167
+ context 'with a blocked command present' do
168
+ context 'with command injection enabled' do
169
+ it 'should raise a RuntimeError' do
170
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
171
+
172
+ expect(TCellAgent).to receive(:policy).with(
173
+ TCellAgent::PolicyTypes::COMMANDINJECTION
174
+ ).and_return(@command_injection_policy)
175
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
176
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(true)
177
+
178
+ expect do
179
+ IO.popen('echo test')
180
+ end.to raise_error(RuntimeError)
181
+ end
182
+ end
183
+ end
184
+
185
+ context 'with env' do
186
+ before(:each) do
187
+ @env = { 'TCELL_VAR' => 'enabled' }
188
+ end
189
+
190
+ context 'with string command' do
191
+ it 'should execute the command' do
192
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
193
+ IO.popen(@env, 'echo', 'w+')
194
+
195
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
196
+ IO.popen(@env, 'echo', 'w+', :unsetenv_others => true)
197
+ end
198
+ end
199
+
200
+ context 'with string command and arguments' do
201
+ it 'should parse the command' do
202
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
203
+ IO.popen(@env, 'echo test')
204
+
205
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
206
+ IO.popen(@env, 'echo test', 'w+')
207
+
208
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
209
+ IO.popen(@env, 'echo test', :unsetenv_others => true)
210
+
211
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
212
+ IO.popen(@env, 'echo test', 'w+', :unsetenv_others => true)
213
+ end
214
+ end
215
+
216
+ context 'with array command' do
217
+ it 'should parse the command properly' do
218
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
219
+ IO.popen(@env, [%w[echo argv0]], 'w+')
220
+
221
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
222
+ IO.popen(@env, [%w[echo argv0]], :unsetenv_others => true)
223
+
224
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
225
+ IO.popen(@env, [%w[echo argv0]], 'w+', :unsetenv_others => true)
226
+
227
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
228
+ IO.popen(@env, ['echo'], 'w+')
229
+
230
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
231
+ IO.popen(@env, ['echo'], :unsetenv_others => true)
232
+
233
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
234
+ IO.popen(@env, ['echo'], 'w+', :unsetenv_others => true)
235
+ end
236
+ end
237
+
238
+ context 'with array command and arguments' do
239
+ it 'should parse the command properly' do
240
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
241
+ IO.popen(@env, [%w[echo argv0], 'test'])
242
+
243
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
244
+ IO.popen(@env, [%w[echo argv0], 'test'], 'w+')
245
+
246
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
247
+ IO.popen(@env, [%w[echo argv0], 'test'], :unsetenv_others => true)
248
+
249
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
250
+ IO.popen(@env, [%w[echo argv0], 'test'], 'w+', :unsetenv_others => true)
251
+
252
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
253
+ IO.popen(@env, %w[echo test])
254
+
255
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
256
+ IO.popen(@env, %w[echo test], 'w+')
257
+
258
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
259
+ IO.popen(@env, %w[echo test], :unsetenv_others => true)
260
+
261
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
262
+ IO.popen(@env, %w[echo test], 'w+', :unsetenv_others => true)
263
+
264
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
265
+ IO.popen([@env, 'echo', 'test', :unsetenv_others => true], 'w+')
266
+
267
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
268
+ IO.popen(@env, [@env, 'echo', 'test', :unsetenv_others => true], 'w+', :err => %i[child out])
269
+ end
270
+ end
271
+ end
272
+
273
+ context 'without env' do
274
+ context 'with array command and arguments' do
275
+ it 'should parse the command properly' do
276
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
277
+ IO.popen([%w[echo argv0], 'test'])
278
+
279
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
280
+ IO.popen([%w[echo argv0], 'test'], 'w+')
281
+
282
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
283
+ IO.popen([%w[echo argv0], 'test'], :unsetenv_others => true)
284
+
285
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
286
+ IO.popen([%w[echo argv0], 'test'], 'w+', :unsetenv_others => true)
287
+
288
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
289
+ IO.popen(%w[echo test])
290
+
291
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
292
+ IO.popen(%w[echo test], 'w+')
293
+
294
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
295
+ IO.popen(%w[echo test], :unsetenv_others => true)
296
+
297
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
298
+ IO.popen(%w[echo test], 'w+', :unsetenv_others => true)
299
+
300
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with(
301
+ "echo -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
302
+ )
303
+ IO.popen(
304
+ [%w[echo argv0],
305
+ '-size',
306
+ '320x85',
307
+ 'canvas:none',
308
+ '-font',
309
+ 'Bookman-DemiItalic',
310
+ '-draw',
311
+ "\"text 25,60 \'Magick\'\""],
312
+ :unsetenv_others => true
313
+ )
314
+ end
315
+ end
316
+ end
317
+ end
318
+ describe '.read' do
319
+ before(:each) do
320
+ native_agent = double('native_agent')
321
+ @command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new(
322
+ native_agent, {}
323
+ )
324
+ end
325
+ context 'empty name' do
326
+ it 'should raise an error' do
327
+ expect do
328
+ IO.read
329
+ end.to raise_error(ArgumentError)
330
+ expect do
331
+ IO.read(nil)
332
+ end.to raise_error(TypeError)
333
+ expect do
334
+ IO.read('')
335
+ end.to raise_error(Errno::ENOENT)
336
+ end
337
+ end
338
+ context 'name starts with a | operator' do
339
+ context 'with an empty or invalid command' do
340
+ it 'should raise an error' do
341
+ expect do
342
+ IO.read('|')
343
+ end.to raise_error(Errno::ENOENT)
344
+
345
+ expect do
346
+ IO.read('|invalid command')
347
+ end.to raise_error(Errno::ENOENT)
348
+
349
+ expect do
350
+ IO.read('|invalid command', 10)
351
+ end.to raise_error(Errno::ENOENT)
352
+
353
+ expect do
354
+ IO.read('|invalid command', 10, 20)
355
+ end.to raise_error(Errno::ENOENT)
356
+ end
357
+ end
358
+ context 'with a valid command' do
359
+ it 'should execute the command' do
360
+ expect(IO.read('|echo test')).to eq("test\n")
361
+ end
362
+ end
363
+ context 'with a non blocked command present' do
364
+ before(:each) do
365
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
366
+ end
367
+ context 'with command injection disabled' do
368
+ it 'should execute the command' do
369
+ expect(@command_injection_policy.enabled).to eq(false)
370
+
371
+ expect(TCellAgent).to receive(:policy).with(
372
+ TCellAgent::PolicyTypes::COMMANDINJECTION
373
+ ).and_return(@command_injection_policy)
374
+ expect(@command_injection_policy).to receive(:enabled).and_call_original
375
+ expect(@command_injection_policy).to_not receive(:block_command?)
376
+
377
+ expect(IO.read('|echo test')).to eq("test\n")
378
+ end
379
+ end
380
+
381
+ context 'with command injection enabled' do
382
+ it 'should execute the command' do
383
+ expect(TCellAgent).to receive(:policy).with(
384
+ TCellAgent::PolicyTypes::COMMANDINJECTION
385
+ ).and_return(@command_injection_policy)
386
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
387
+ expect(@command_injection_policy).to receive(:block_command?).and_return(false)
388
+
389
+ expect(IO.read('|echo test')).to eq("test\n")
390
+ end
391
+ end
392
+ end
393
+
394
+ context 'with a blocked command present' do
395
+ context 'with command injection enabled' do
396
+ it 'should raise a RuntimeError' do
397
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
398
+
399
+ expect(TCellAgent).to receive(:policy).with(
400
+ TCellAgent::PolicyTypes::COMMANDINJECTION
401
+ ).and_return(@command_injection_policy)
402
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
403
+ expect(@command_injection_policy).to receive(:block_command?).and_return(true)
404
+
405
+ expect do
406
+ IO.read('|echo test')
407
+ end.to raise_error(RuntimeError)
408
+ end
409
+ end
410
+ end
411
+ end
412
+ end
413
+ describe '.readlines' do
414
+ before(:each) do
415
+ native_agent = double('native_agent')
416
+ @command_injection_policy = TCellAgent::Policies::CommandInjectionPolicy.new(
417
+ native_agent, {}
418
+ )
419
+ end
420
+ context 'empty name' do
421
+ it 'should raise an error' do
422
+ expect do
423
+ IO.readlines
424
+ end.to raise_error(ArgumentError)
425
+ expect do
426
+ IO.readlines(nil)
427
+ end.to raise_error(TypeError)
428
+ expect do
429
+ IO.readlines('')
430
+ end.to raise_error(Errno::ENOENT)
431
+ end
432
+ end
433
+ context 'name starts with a | operator' do
434
+ context 'with an empty or invalid command' do
435
+ it 'should raise an error' do
436
+ expect do
437
+ IO.readlines('|')
438
+ end.to raise_error(Errno::ENOENT)
439
+
440
+ expect do
441
+ IO.readlines('|invalid command')
442
+ end.to raise_error(Errno::ENOENT)
443
+
444
+ expect do
445
+ IO.readlines('|invalid command', 10)
446
+ end.to raise_error(Errno::ENOENT)
447
+ end
448
+ end
449
+ context 'with a valid command' do
450
+ it 'should execute the command' do
451
+ expect(IO.readlines('|echo test')[0]).to eq("test\n")
452
+ end
453
+ end
454
+ context 'with a non blocked command present' do
455
+ before(:each) do
456
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
457
+ end
458
+ context 'with command injection disabled' do
459
+ it 'should execute the command' do
460
+ expect(@command_injection_policy.enabled).to eq(false)
461
+
462
+ expect(TCellAgent).to receive(:policy).with(
463
+ TCellAgent::PolicyTypes::COMMANDINJECTION
464
+ ).and_return(@command_injection_policy)
465
+ expect(@command_injection_policy).to receive(:enabled).and_call_original
466
+ expect(@command_injection_policy).to_not receive(:block_command?)
467
+
468
+ expect(IO.readlines('|echo test')[0]).to eq("test\n")
469
+ end
470
+ end
471
+
472
+ context 'with command injection enabled' do
473
+ it 'should execute the command' do
474
+ expect(TCellAgent).to receive(:policy).with(
475
+ TCellAgent::PolicyTypes::COMMANDINJECTION
476
+ ).and_return(@command_injection_policy)
477
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
478
+ expect(@command_injection_policy).to receive(:block_command?).and_return(false)
479
+
480
+ expect(IO.readlines('|echo test')[0]).to eq("test\n")
481
+ end
482
+ end
483
+ end
484
+
485
+ context 'with a blocked command present' do
486
+ context 'with command injection enabled' do
487
+ it 'should raise a RuntimeError' do
488
+ allow_any_instance_of(TCellAgent::Agent).to receive(:safe_to_check_cmdi).and_return(true)
489
+
490
+ expect(TCellAgent).to receive(:policy).with(
491
+ TCellAgent::PolicyTypes::COMMANDINJECTION
492
+ ).and_return(@command_injection_policy)
493
+ expect(@command_injection_policy).to receive(:enabled).and_return(true)
494
+ expect(@command_injection_policy).to receive(:block_command?).with('echo test', nil).and_return(true)
495
+
496
+ expect do
497
+ IO.readlines('|echo test')
498
+ end.to raise_error(RuntimeError)
499
+ end
500
+ end
501
+ end
502
+ end
503
+ end
504
+ end