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.
- checksums.yaml +5 -5
- data/bin/tcell_agent +45 -137
- data/lib/tcell_agent.rb +12 -14
- data/lib/tcell_agent/agent.rb +108 -97
- data/lib/tcell_agent/agent/route_manager.rb +0 -16
- data/lib/tcell_agent/agent/static_agent.rb +9 -30
- data/lib/tcell_agent/config_initializer.rb +66 -0
- data/lib/tcell_agent/configuration.rb +69 -345
- data/lib/tcell_agent/hooks/login_fraud.rb +30 -33
- data/lib/tcell_agent/instrument_servers.rb +23 -0
- data/lib/tcell_agent/instrumentation.rb +12 -10
- data/lib/tcell_agent/instrumentation/cmdi.rb +29 -25
- data/lib/tcell_agent/instrumentation/lfi.rb +84 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +25 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +131 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +102 -0
- data/lib/tcell_agent/logger.rb +49 -114
- data/lib/tcell_agent/patches.rb +6 -7
- data/lib/tcell_agent/policies/appfirewall_policy.rb +26 -0
- data/lib/tcell_agent/policies/command_injection_policy.rb +28 -0
- data/lib/tcell_agent/policies/dataloss_policy.rb +44 -44
- data/lib/tcell_agent/policies/headers_policy.rb +25 -0
- data/lib/tcell_agent/policies/http_redirect_policy.rb +13 -79
- data/lib/tcell_agent/policies/js_agent_policy.rb +27 -0
- data/lib/tcell_agent/policies/local_file_access.rb +28 -0
- data/lib/tcell_agent/policies/login_policy.rb +43 -0
- data/lib/tcell_agent/policies/patches_policy.rb +27 -0
- data/lib/tcell_agent/policies/policies_manager.rb +68 -0
- data/lib/tcell_agent/policies/policy_polling.rb +58 -0
- data/lib/tcell_agent/policies/policy_types.rb +14 -0
- data/lib/tcell_agent/policies/system_enablements.rb +27 -0
- data/lib/tcell_agent/rails/auth/authlogic.rb +46 -75
- data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
- data/lib/tcell_agent/rails/auth/devise.rb +100 -105
- data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +62 -76
- data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
- data/lib/tcell_agent/rails/csrf_exception.rb +2 -10
- data/lib/tcell_agent/rails/dlp.rb +35 -23
- data/lib/tcell_agent/rails/dlp_handler.rb +1 -2
- data/lib/tcell_agent/rails/js_agent_insert.rb +12 -13
- data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +4 -25
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -12
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +1 -2
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +14 -34
- data/lib/tcell_agent/{rails.rb → rails/railties/tcell_agent_railties.rb} +11 -16
- data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
- data/lib/tcell_agent/rails/routes.rb +10 -12
- data/lib/tcell_agent/rails/routes/grape.rb +4 -14
- data/lib/tcell_agent/rails/routes/route_id.rb +3 -1
- data/lib/tcell_agent/rails/settings_reporter.rb +23 -36
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +5 -4
- data/lib/tcell_agent/rust/agent_config.rb +60 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-1.3.2.so → libtcellagent-5.0.2.dylib} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-1.3.2.so → libtcellagent-5.0.2.so} +0 -0
- data/lib/tcell_agent/rust/libtcellagent-alpine-5.0.2.so +0 -0
- data/lib/tcell_agent/rust/models.rb +6 -52
- data/lib/tcell_agent/rust/native_agent.rb +549 -0
- data/lib/tcell_agent/rust/native_agent_response.rb +42 -0
- data/lib/tcell_agent/rust/native_library.rb +69 -0
- data/lib/tcell_agent/rust/tcellagent-5.0.2.dll +0 -0
- data/lib/tcell_agent/sensor_events/agent_setting_event.rb +12 -0
- data/lib/tcell_agent/sensor_events/{app_config.rb → app_config_setting_event.rb} +0 -6
- data/lib/tcell_agent/sensor_events/dlp.rb +2 -6
- data/lib/tcell_agent/sensor_events/sensor.rb +0 -62
- data/lib/tcell_agent/sensor_events/server_agent.rb +13 -18
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +0 -108
- data/lib/tcell_agent/sensor_events/util/utils.rb +0 -2
- data/lib/tcell_agent/servers/passenger.rb +1 -28
- data/lib/tcell_agent/servers/puma.rb +3 -21
- data/lib/tcell_agent/servers/rails_server.rb +1 -2
- data/lib/tcell_agent/servers/thin.rb +2 -2
- data/lib/tcell_agent/servers/unicorn.rb +19 -80
- data/lib/tcell_agent/servers/webrick.rb +1 -2
- data/lib/tcell_agent/settings_reporter.rb +11 -90
- data/lib/tcell_agent/sinatra.rb +14 -16
- data/lib/tcell_agent/tcell_context.rb +40 -14
- data/lib/tcell_agent/utils/headers.rb +14 -0
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/lib/tcell_agent/configuration_spec.rb +55 -346
- data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +46 -173
- data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +504 -0
- data/spec/lib/tcell_agent/instrumentation/cmdi/kernel_cmdi_spec.rb +435 -0
- data/spec/lib/tcell_agent/instrumentation/cmdi_spec.rb +201 -0
- data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +326 -0
- data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +562 -0
- data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +264 -0
- data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +150 -0
- data/spec/lib/tcell_agent/patches_spec.rb +25 -43
- data/spec/lib/tcell_agent/policies/appfirewall_policy_spec.rb +183 -0
- data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +57 -0
- data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +84 -773
- data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +161 -0
- data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +9 -9
- data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +243 -198
- data/spec/lib/tcell_agent/policies/js_agent_policy_spec.rb +75 -0
- data/spec/lib/tcell_agent/policies/login_policy_spec.rb +165 -33
- data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +84 -277
- data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +104 -0
- data/spec/lib/tcell_agent/policies/policy_polling_spec.rb +6 -0
- data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +56 -0
- data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +9 -18
- data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +13 -30
- data/spec/lib/tcell_agent/rails/logger_spec.rb +27 -7
- data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +17 -12
- data/spec/lib/tcell_agent/rails/routes/routes_spec.rb +14 -14
- data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
- data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +0 -35
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +56 -155
- data/spec/spec_helper.rb +1 -1
- data/spec/support/builders.rb +103 -0
- data/spec/support/force_logger_mocking.rb +38 -0
- data/spec/support/resources/lfi_sample_file.txt +2 -0
- data/spec/support/static_agent_overrides.rb +0 -15
- metadata +72 -83
- data/lib/tcell_agent/agent/event_processor.rb +0 -326
- data/lib/tcell_agent/agent/fork_pipe_manager.rb +0 -113
- data/lib/tcell_agent/agent/policy_manager.rb +0 -219
- data/lib/tcell_agent/agent/policy_types.rb +0 -30
- data/lib/tcell_agent/api.rb +0 -91
- data/lib/tcell_agent/appsensor/injections_reporter.rb +0 -24
- data/lib/tcell_agent/authlogic.rb +0 -26
- data/lib/tcell_agent/config/child_process_events.rb +0 -8
- data/lib/tcell_agent/config/unknown_options.rb +0 -123
- data/lib/tcell_agent/devise.rb +0 -35
- data/lib/tcell_agent/instrumentation/cmdi/backtick.rb +0 -10
- data/lib/tcell_agent/instrumentation/cmdi/exec.rb +0 -14
- data/lib/tcell_agent/instrumentation/cmdi/popen.rb +0 -28
- data/lib/tcell_agent/instrumentation/cmdi/spawn.rb +0 -11
- data/lib/tcell_agent/instrumentation/cmdi/system.rb +0 -11
- data/lib/tcell_agent/policies/http_tx_policy.rb +0 -60
- data/lib/tcell_agent/policies/login_fraud_policy.rb +0 -45
- data/lib/tcell_agent/policies/rust_policies.rb +0 -110
- data/lib/tcell_agent/rails/on_start.rb +0 -41
- data/lib/tcell_agent/rust/libtcellagent-1.3.2.dylib +0 -0
- data/lib/tcell_agent/rust/tcellagent-1.3.2.dll +0 -0
- data/lib/tcell_agent/rust/whisperer.rb +0 -308
- data/lib/tcell_agent/sensor_events/appsensor_event.rb +0 -52
- data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +0 -45
- data/lib/tcell_agent/sensor_events/command_injection.rb +0 -75
- data/lib/tcell_agent/sensor_events/honeytokens.rb +0 -16
- data/lib/tcell_agent/sensor_events/login_fraud.rb +0 -60
- data/lib/tcell_agent/sensor_events/metrics.rb +0 -123
- data/lib/tcell_agent/sensor_events/patches.rb +0 -21
- data/lib/tcell_agent/start_background_thread.rb +0 -55
- data/lib/tcell_agent/system_info.rb +0 -11
- data/lib/tcell_agent/utils/io.rb +0 -38
- data/lib/tcell_agent/utils/passwords.rb +0 -28
- data/lib/tcell_agent/utils/queue_with_timeout.rb +0 -142
- data/spec/lib/tcell_agent/agent/fork_pipe_manager_spec.rb +0 -100
- data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +0 -535
- data/spec/lib/tcell_agent/agent/static_agent_spec.rb +0 -133
- data/spec/lib/tcell_agent/api/api_spec.rb +0 -39
- data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +0 -187
- data/spec/lib/tcell_agent/cmdi_spec.rb +0 -736
- data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -213
- data/spec/lib/tcell_agent/instrumentation_spec.rb +0 -225
- data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +0 -517
- data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +0 -22
- data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +0 -293
- data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +0 -198
- data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +0 -180
- data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +0 -116
- data/spec/lib/tcell_agent/rust/models_spec.rb +0 -120
- data/spec/lib/tcell_agent/rust/whisperer_spec.rb +0 -704
- data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +0 -45
- data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +0 -272
- data/spec/lib/tcell_agent/utils/bounded_queue_spec.rb +0 -52
- data/spec/lib/tcell_agent/utils/passwords_spec.rb +0 -143
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
module TCellAgent
|
|
4
|
-
module SensorEvents
|
|
5
|
-
describe Agent do
|
|
6
|
-
describe '.increment_session_info' do
|
|
7
|
-
context 'when running the parent process' do
|
|
8
|
-
it 'should increment the session info' do
|
|
9
|
-
expect(TCellAgent::Agent).to receive(:parent_process?).and_return(true)
|
|
10
|
-
expect(TCellAgent).to_not receive(:queue_metric)
|
|
11
|
-
expect_any_instance_of(SessionsMetric).to receive(:add_session_info).with(
|
|
12
|
-
'hmac_session_id', 'user_id', 'ip_address', 'user_agent'
|
|
13
|
-
)
|
|
14
|
-
expect_any_instance_of(SessionsMetric).to receive(:flush).and_return(false)
|
|
15
|
-
expect(TCellAgent).to_not receive(:send_event)
|
|
16
|
-
|
|
17
|
-
TCellAgent.increment_session_info('hmac_session_id', 'user_id', 'ip_address', 'user_agent')
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
context 'and the session becomes full' do
|
|
21
|
-
it 'should increment the session info and send the flush dummy event' do
|
|
22
|
-
expect(TCellAgent::Agent).to receive(:parent_process?).and_return(true)
|
|
23
|
-
expect(TCellAgent).to_not receive(:queue_metric)
|
|
24
|
-
expect_any_instance_of(SessionsMetric).to receive(:add_session_info).with(
|
|
25
|
-
'hmac_session_id', 'user_id', 'ip_address', 'user_agent'
|
|
26
|
-
)
|
|
27
|
-
expect_any_instance_of(SessionsMetric).to receive(:flush).and_return(true)
|
|
28
|
-
expect(TCellAgent).to receive(:send_event).with(
|
|
29
|
-
instance_of(TCellAgent::SensorEvents::FlushDummyEvent)
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
TCellAgent.increment_session_info('hmac_session_id', 'user_id', 'ip_address', 'user_agent')
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
context 'when NOT running the parent process' do
|
|
38
|
-
it 'should queue the metric' do
|
|
39
|
-
expect(TCellAgent::Agent).to receive(:parent_process?).and_return(false)
|
|
40
|
-
expect(TCellAgent).to receive(:queue_metric).with(
|
|
41
|
-
{
|
|
42
|
-
'_type' => 'increment_session_info',
|
|
43
|
-
'hmac_session_id' => 'hmac_session_id',
|
|
44
|
-
'user_id' => 'user_id',
|
|
45
|
-
'ip_address' => 'ip_address',
|
|
46
|
-
'user_agent' => 'user_agent'
|
|
47
|
-
}
|
|
48
|
-
)
|
|
49
|
-
expect_any_instance_of(SessionsMetric).to_not receive(:add_session_info)
|
|
50
|
-
expect_any_instance_of(SessionsMetric).to_not receive(:flush)
|
|
51
|
-
expect(TCellAgent).to_not receive(:send_event)
|
|
52
|
-
|
|
53
|
-
TCellAgent.increment_session_info('hmac_session_id', 'user_id', 'ip_address', 'user_agent')
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
describe '.increment_route' do
|
|
59
|
-
context 'when running the parent process' do
|
|
60
|
-
before(:each) do
|
|
61
|
-
TCellAgent.thread_agent.response_time_table = {}
|
|
62
|
-
end
|
|
63
|
-
after(:each) do
|
|
64
|
-
TCellAgent.thread_agent.response_time_table = {}
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
context 'with a route present' do
|
|
68
|
-
it 'should increment the route info' do
|
|
69
|
-
expect(TCellAgent::Agent).to receive(:parent_process?).and_return(true)
|
|
70
|
-
expect(TCellAgent).to_not receive(:queue_metric)
|
|
71
|
-
|
|
72
|
-
TCellAgent.increment_route('/ma_route', 20)
|
|
73
|
-
|
|
74
|
-
expect(TCellAgent.thread_agent.response_time_table).to eq(
|
|
75
|
-
{ '/ma_route' => { 'c' => 1, 'mx' => 20, 'mn' => 20, 't' => 20 } }
|
|
76
|
-
)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
context 'with an empty route' do
|
|
81
|
-
it 'should increment the route info' do
|
|
82
|
-
expect(TCellAgent::Agent).to receive(:parent_process?).and_return(true)
|
|
83
|
-
expect(TCellAgent).to_not receive(:queue_metric)
|
|
84
|
-
|
|
85
|
-
TCellAgent.increment_route('', 20)
|
|
86
|
-
|
|
87
|
-
expect(TCellAgent.thread_agent.response_time_table).to eq(
|
|
88
|
-
{ '?' => { 'c' => 1, 'mx' => 20, 'mn' => 20, 't' => 20 } }
|
|
89
|
-
)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
context 'with a nil route' do
|
|
94
|
-
it 'should increment the route info' do
|
|
95
|
-
expect(TCellAgent::Agent).to receive(:parent_process?).and_return(true)
|
|
96
|
-
expect(TCellAgent).to_not receive(:queue_metric)
|
|
97
|
-
|
|
98
|
-
TCellAgent.increment_route(nil, 20)
|
|
99
|
-
|
|
100
|
-
expect(TCellAgent.thread_agent.response_time_table).to eq(
|
|
101
|
-
{ '?' => { 'c' => 1, 'mx' => 20, 'mn' => 20, 't' => 20 } }
|
|
102
|
-
)
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
context 'when NOT running the parent process' do
|
|
108
|
-
before(:each) do
|
|
109
|
-
TCellAgent.thread_agent.response_time_table = {}
|
|
110
|
-
end
|
|
111
|
-
after(:each) do
|
|
112
|
-
TCellAgent.thread_agent.response_time_table = {}
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
it 'should queue the metric' do
|
|
116
|
-
expect(TCellAgent::Agent).to receive(:parent_process?).and_return(false)
|
|
117
|
-
expect(TCellAgent).to receive(:queue_metric).with(
|
|
118
|
-
{
|
|
119
|
-
'_type' => 'increment_route',
|
|
120
|
-
'route_id' => '/ma_route',
|
|
121
|
-
'response_time' => 20
|
|
122
|
-
}
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
TCellAgent.increment_route('/ma_route', 20)
|
|
126
|
-
|
|
127
|
-
expect(TCellAgent.thread_agent.response_time_table).to eq({})
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'addressable/template'
|
|
3
|
-
|
|
4
|
-
module TCellAgent
|
|
5
|
-
class TCellApi
|
|
6
|
-
describe 'successful POST on /user/create' do
|
|
7
|
-
it 'should redirect to dashboard' do
|
|
8
|
-
tapi = TCellApi.new
|
|
9
|
-
TCellAgent.configuration.app_id = 'test-appid'
|
|
10
|
-
TCellAgent.configuration.api_key = 'test-apikey'
|
|
11
|
-
|
|
12
|
-
def checkreq(_req)
|
|
13
|
-
'{"result":{"csp-headers":{"app_id":"testapp-Becwu","policy_id":' \
|
|
14
|
-
'"acf60560-4e76-11e5-874c-7d71d425b275","headers":[{"name":"Content-Security-Policy-Report-Only",' \
|
|
15
|
-
'"value":"font-src \'none\'; script-src \'self\'; reflected-xss block; ' \
|
|
16
|
-
'style-src \'self\'; connect-src' \
|
|
17
|
-
' \'none\'" ,"report-uri":"http://localhost:3000/csp/cab5e750e66d614bd46fd07a7078db1e74b4f427b2a135b2c96eca684a642707"}]}}}'
|
|
18
|
-
end
|
|
19
|
-
uri_template =
|
|
20
|
-
Addressable::Template.new 'https://api.tcell.io/agents/api/v1/apps/test-appid/policies/latest?type=patches:v1'
|
|
21
|
-
|
|
22
|
-
stub_request(:any, uri_template).to_return(
|
|
23
|
-
lambda { |request|
|
|
24
|
-
{
|
|
25
|
-
:body => checkreq(request),
|
|
26
|
-
:status => 200,
|
|
27
|
-
:headers => { 'Content-Type' => 'application/json' }
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
result = tapi.poll_api
|
|
33
|
-
TCellAgent.configuration.app_id = nil
|
|
34
|
-
TCellAgent.configuration.api_key = nil
|
|
35
|
-
expect(result['result']['csp-headers']['app_id']).to eq('testapp-Becwu')
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
module TCellAgent
|
|
4
|
-
module AppSensor
|
|
5
|
-
describe InjectionsReporter do
|
|
6
|
-
describe '.report_and_log' do
|
|
7
|
-
context 'with nil events' do
|
|
8
|
-
it 'should do nothing' do
|
|
9
|
-
expect(TCellAgent).to_not receive(:send_event)
|
|
10
|
-
expect(TCellAgent).to_not receive(:logger)
|
|
11
|
-
|
|
12
|
-
InjectionsReporter.report_and_log(nil)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
context 'with empty events' do
|
|
17
|
-
it 'should do nothing' do
|
|
18
|
-
expect(TCellAgent).to_not receive(:send_event)
|
|
19
|
-
expect(TCellAgent).to_not receive(:logger)
|
|
20
|
-
|
|
21
|
-
InjectionsReporter.report_and_log([])
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
context 'with one event' do
|
|
26
|
-
it 'should send the event' do
|
|
27
|
-
events = [
|
|
28
|
-
{
|
|
29
|
-
'pattern' => '1',
|
|
30
|
-
'method' => 'request_method',
|
|
31
|
-
'uri' => 'abosolute_uri',
|
|
32
|
-
'parameter' => 'avatar',
|
|
33
|
-
'meta' => { 'l' => 'body' },
|
|
34
|
-
'session_id' => 'session_id',
|
|
35
|
-
'route_id' => 'route_id',
|
|
36
|
-
'detection_point' => 'xss',
|
|
37
|
-
'user_id' => 'user_id'
|
|
38
|
-
}
|
|
39
|
-
]
|
|
40
|
-
|
|
41
|
-
expect(TCellAgent).to_not receive(:logger)
|
|
42
|
-
|
|
43
|
-
expect(TCellAgent).to receive(:send_event).with(
|
|
44
|
-
{
|
|
45
|
-
'event_type' => 'as',
|
|
46
|
-
'dp' => 'xss',
|
|
47
|
-
'param' => 'avatar',
|
|
48
|
-
'm' => 'request_method',
|
|
49
|
-
'pattern' => '1',
|
|
50
|
-
'meta' => { 'l' => 'body' },
|
|
51
|
-
'rid' => 'route_id',
|
|
52
|
-
'uri' => 'abosolute_uri',
|
|
53
|
-
'uid' => 'user_id',
|
|
54
|
-
'sid' => 'session_id'
|
|
55
|
-
}
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
InjectionsReporter.report_and_log(events)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
context 'with one event with full payload' do
|
|
63
|
-
it 'should send and log the event' do
|
|
64
|
-
events = [
|
|
65
|
-
{
|
|
66
|
-
'pattern' => '1',
|
|
67
|
-
'method' => 'request_method',
|
|
68
|
-
'uri' => 'abosolute_uri',
|
|
69
|
-
'parameter' => 'avatar',
|
|
70
|
-
'meta' => { 'l' => 'body' },
|
|
71
|
-
'session_id' => 'session_id',
|
|
72
|
-
'route_id' => 'route_id',
|
|
73
|
-
'detection_point' => 'xss',
|
|
74
|
-
'user_id' => 'user_id',
|
|
75
|
-
'full_payload' => 'full_payload'
|
|
76
|
-
}
|
|
77
|
-
]
|
|
78
|
-
|
|
79
|
-
logger = double('logger')
|
|
80
|
-
|
|
81
|
-
expect(TCellAgent).to receive(:logger).and_return(logger)
|
|
82
|
-
expect(logger).to receive(:info).with(/"payload":"full_payload"/)
|
|
83
|
-
|
|
84
|
-
expect(TCellAgent).to receive(:send_event).with(
|
|
85
|
-
{
|
|
86
|
-
'event_type' => 'as',
|
|
87
|
-
'dp' => 'xss',
|
|
88
|
-
'param' => 'avatar',
|
|
89
|
-
'm' => 'request_method',
|
|
90
|
-
'pattern' => '1',
|
|
91
|
-
'meta' => { 'l' => 'body' },
|
|
92
|
-
'rid' => 'route_id',
|
|
93
|
-
'uri' => 'abosolute_uri',
|
|
94
|
-
'uid' => 'user_id',
|
|
95
|
-
'sid' => 'session_id'
|
|
96
|
-
}
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
InjectionsReporter.report_and_log(events)
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
context 'with one event with payload' do
|
|
104
|
-
it 'should send the event' do
|
|
105
|
-
events = [
|
|
106
|
-
{
|
|
107
|
-
'pattern' => '1',
|
|
108
|
-
'method' => 'request_method',
|
|
109
|
-
'uri' => 'abosolute_uri',
|
|
110
|
-
'parameter' => 'avatar',
|
|
111
|
-
'meta' => { 'l' => 'body' },
|
|
112
|
-
'session_id' => 'session_id',
|
|
113
|
-
'route_id' => 'route_id',
|
|
114
|
-
'detection_point' => 'xss',
|
|
115
|
-
'user_id' => 'user_id',
|
|
116
|
-
'payload' => 'payload'
|
|
117
|
-
}
|
|
118
|
-
]
|
|
119
|
-
|
|
120
|
-
expect(TCellAgent).to_not receive(:logger)
|
|
121
|
-
|
|
122
|
-
expect(TCellAgent).to receive(:send_event).with(
|
|
123
|
-
{
|
|
124
|
-
'event_type' => 'as',
|
|
125
|
-
'dp' => 'xss',
|
|
126
|
-
'param' => 'avatar',
|
|
127
|
-
'm' => 'request_method',
|
|
128
|
-
'pattern' => '1',
|
|
129
|
-
'meta' => { 'l' => 'body' },
|
|
130
|
-
'rid' => 'route_id',
|
|
131
|
-
'uri' => 'abosolute_uri',
|
|
132
|
-
'uid' => 'user_id',
|
|
133
|
-
'sid' => 'session_id',
|
|
134
|
-
'payload' => 'payload'
|
|
135
|
-
}
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
InjectionsReporter.report_and_log(events)
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
context 'with one event with payload and full payload' do
|
|
143
|
-
it 'should send and log the event' do
|
|
144
|
-
events = [
|
|
145
|
-
{
|
|
146
|
-
'pattern' => '1',
|
|
147
|
-
'method' => 'request_method',
|
|
148
|
-
'uri' => 'abosolute_uri',
|
|
149
|
-
'parameter' => 'avatar',
|
|
150
|
-
'meta' => { 'l' => 'body' },
|
|
151
|
-
'session_id' => 'session_id',
|
|
152
|
-
'route_id' => 'route_id',
|
|
153
|
-
'detection_point' => 'xss',
|
|
154
|
-
'user_id' => 'user_id',
|
|
155
|
-
'payload' => 'payload',
|
|
156
|
-
'full_payload' => 'full_payload'
|
|
157
|
-
}
|
|
158
|
-
]
|
|
159
|
-
|
|
160
|
-
logger = double('logger')
|
|
161
|
-
|
|
162
|
-
expect(TCellAgent).to receive(:logger).and_return(logger)
|
|
163
|
-
expect(logger).to receive(:info).with(/"payload":"full_payload"/)
|
|
164
|
-
|
|
165
|
-
expect(TCellAgent).to receive(:send_event).with(
|
|
166
|
-
{
|
|
167
|
-
'event_type' => 'as',
|
|
168
|
-
'dp' => 'xss',
|
|
169
|
-
'param' => 'avatar',
|
|
170
|
-
'm' => 'request_method',
|
|
171
|
-
'pattern' => '1',
|
|
172
|
-
'meta' => { 'l' => 'body' },
|
|
173
|
-
'rid' => 'route_id',
|
|
174
|
-
'uri' => 'abosolute_uri',
|
|
175
|
-
'uid' => 'user_id',
|
|
176
|
-
'sid' => 'session_id',
|
|
177
|
-
'payload' => 'payload'
|
|
178
|
-
}
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
InjectionsReporter.report_and_log(events)
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
end
|
|
186
|
-
end
|
|
187
|
-
end
|
|
@@ -1,736 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
module TCellAgent
|
|
4
|
-
module Cmdi
|
|
5
|
-
describe '.parse_command' do
|
|
6
|
-
context 'with env' do
|
|
7
|
-
before(:each) do
|
|
8
|
-
@env = { 'TCELL_VAR' => 'enabled' }
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
context 'with string command' do
|
|
12
|
-
it 'should parse the command properly' do
|
|
13
|
-
cmd = TCellAgent::Cmdi.parse_command(@env, 'echo')
|
|
14
|
-
expect(cmd).to eq('echo')
|
|
15
|
-
|
|
16
|
-
cmd = TCellAgent::Cmdi.parse_command(@env, 'echo', :unsetenv_others => true)
|
|
17
|
-
expect(cmd).to eq('echo')
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
context 'with string command and arguments' do
|
|
22
|
-
it 'should parse the command' do
|
|
23
|
-
cmd = TCellAgent::Cmdi.parse_command(@env, 'echo', 'test', :unsetenv_others => true)
|
|
24
|
-
expect(cmd).to eq('echo test')
|
|
25
|
-
|
|
26
|
-
cmd = TCellAgent::Cmdi.parse_command(@env, 'echo', 'test', 'one', :unsetenv_others => true)
|
|
27
|
-
expect(cmd).to eq('echo test one')
|
|
28
|
-
|
|
29
|
-
cmd = TCellAgent::Cmdi.parse_command(
|
|
30
|
-
@env,
|
|
31
|
-
'magick',
|
|
32
|
-
'-size',
|
|
33
|
-
'320x85',
|
|
34
|
-
'canvas:none',
|
|
35
|
-
'-font',
|
|
36
|
-
'Bookman-DemiItalic',
|
|
37
|
-
'-draw',
|
|
38
|
-
"\"text 25,60 \'Magick\'\"",
|
|
39
|
-
:unsetenv_others => true
|
|
40
|
-
)
|
|
41
|
-
expect(cmd).to eq(
|
|
42
|
-
"magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
|
|
43
|
-
)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
context 'with array command' do
|
|
48
|
-
it 'should parse the command properly' do
|
|
49
|
-
cmd = TCellAgent::Cmdi.parse_command(@env, %w[echo argv0], :unsetenv_others => true)
|
|
50
|
-
expect(cmd).to eq('echo')
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
context 'with array command and arguments' do
|
|
55
|
-
it 'should parse the command properly' do
|
|
56
|
-
cmd = TCellAgent::Cmdi.parse_command(@env, %w[echo argv0], 'test', :unsetenv_others => true)
|
|
57
|
-
expect(cmd).to eq('echo test')
|
|
58
|
-
|
|
59
|
-
cmd = TCellAgent::Cmdi.parse_command(@env, %w[echo argv0], 'test', 'one', :unsetenv_others => true)
|
|
60
|
-
expect(cmd).to eq('echo test one')
|
|
61
|
-
|
|
62
|
-
cmd = TCellAgent::Cmdi.parse_command(
|
|
63
|
-
@env,
|
|
64
|
-
%w[magick argv0],
|
|
65
|
-
'-size',
|
|
66
|
-
'320x85',
|
|
67
|
-
'canvas:none',
|
|
68
|
-
'-font',
|
|
69
|
-
'Bookman-DemiItalic',
|
|
70
|
-
'-draw',
|
|
71
|
-
"\"text 25,60 \'Magick\'\"",
|
|
72
|
-
:unsetenv_others => true
|
|
73
|
-
)
|
|
74
|
-
expect(cmd).to eq(
|
|
75
|
-
"magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
|
|
76
|
-
)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
context 'without env' do
|
|
82
|
-
context 'with string command' do
|
|
83
|
-
it 'should parse the command properly' do
|
|
84
|
-
cmd = TCellAgent::Cmdi.parse_command('echo')
|
|
85
|
-
expect(cmd).to eq('echo')
|
|
86
|
-
|
|
87
|
-
cmd = TCellAgent::Cmdi.parse_command('echo', :unsetenv_others => true)
|
|
88
|
-
expect(cmd).to eq('echo')
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
context 'with string command and arguments' do
|
|
93
|
-
it 'should parse the command' do
|
|
94
|
-
cmd = TCellAgent::Cmdi.parse_command('echo', 'test', :unsetenv_others => true)
|
|
95
|
-
expect(cmd).to eq('echo test')
|
|
96
|
-
|
|
97
|
-
cmd = TCellAgent::Cmdi.parse_command('echo', 'test', 'one', :unsetenv_others => true)
|
|
98
|
-
expect(cmd).to eq('echo test one')
|
|
99
|
-
|
|
100
|
-
cmd = TCellAgent::Cmdi.parse_command(
|
|
101
|
-
'magick',
|
|
102
|
-
'-size',
|
|
103
|
-
'320x85',
|
|
104
|
-
'canvas:none',
|
|
105
|
-
'-font',
|
|
106
|
-
'Bookman-DemiItalic',
|
|
107
|
-
'-draw',
|
|
108
|
-
"\"text 25,60 \'Magick\'\"",
|
|
109
|
-
:unsetenv_others => true
|
|
110
|
-
)
|
|
111
|
-
expect(cmd).to eq(
|
|
112
|
-
"magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
|
|
113
|
-
)
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
context 'with array command' do
|
|
118
|
-
it 'should parse the command properly' do
|
|
119
|
-
cmd = TCellAgent::Cmdi.parse_command(%w[echo argv0], :unsetenv_others => true)
|
|
120
|
-
expect(cmd).to eq('echo')
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
context 'with array command and arguments' do
|
|
125
|
-
it 'should parse the command properly' do
|
|
126
|
-
cmd = TCellAgent::Cmdi.parse_command(%w[echo argv0], 'test', :unsetenv_others => true)
|
|
127
|
-
expect(cmd).to eq('echo test')
|
|
128
|
-
|
|
129
|
-
cmd = TCellAgent::Cmdi.parse_command(%w[echo argv0], 'test', 'one', :unsetenv_others => true)
|
|
130
|
-
expect(cmd).to eq('echo test one')
|
|
131
|
-
|
|
132
|
-
cmd = TCellAgent::Cmdi.parse_command(
|
|
133
|
-
%w[magick argv0],
|
|
134
|
-
'-size',
|
|
135
|
-
'320x85',
|
|
136
|
-
'canvas:none',
|
|
137
|
-
'-font',
|
|
138
|
-
'Bookman-DemiItalic',
|
|
139
|
-
'-draw',
|
|
140
|
-
"\"text 25,60 \'Magick\'\"",
|
|
141
|
-
:unsetenv_others => true
|
|
142
|
-
)
|
|
143
|
-
expect(cmd).to eq(
|
|
144
|
-
"magick -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
|
|
145
|
-
)
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
describe IO do
|
|
153
|
-
describe '.popen' do
|
|
154
|
-
before(:each) do
|
|
155
|
-
configuration = double(
|
|
156
|
-
'configuration',
|
|
157
|
-
{
|
|
158
|
-
'app_id' => 'app_id',
|
|
159
|
-
'api_key' => 'api_key',
|
|
160
|
-
'allow_payloads' => true,
|
|
161
|
-
'js_agent_api_base_url' => 'http://api.tcell.com/',
|
|
162
|
-
'js_agent_url' => 'https://jsagent.tcell.io/tcellagent.min.js',
|
|
163
|
-
'max_csp_header_bytes' => nil,
|
|
164
|
-
'event_time_limit_seconds' => 15,
|
|
165
|
-
'event_batch_size_limit' => 50,
|
|
166
|
-
'preload_policy_filename' => nil,
|
|
167
|
-
'cache_filename_with_app_id' => '/tcellagent_src/tcell/cache/tcell_agent.cache',
|
|
168
|
-
'agent_home_owner' => nil
|
|
169
|
-
}
|
|
170
|
-
)
|
|
171
|
-
expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
|
|
172
|
-
@rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
context 'empty command' do
|
|
176
|
-
it 'should raise an error' do
|
|
177
|
-
expect do
|
|
178
|
-
IO.popen
|
|
179
|
-
end.to raise_error(ArgumentError)
|
|
180
|
-
expect do
|
|
181
|
-
IO.popen(nil)
|
|
182
|
-
end.to raise_error(TypeError)
|
|
183
|
-
expect do
|
|
184
|
-
IO.popen('')
|
|
185
|
-
end.to raise_error(Errno::ENOENT)
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
context 'non existent command' do
|
|
190
|
-
it 'should return nil' do
|
|
191
|
-
expect do
|
|
192
|
-
IO.popen('foobar')
|
|
193
|
-
end.to raise_error(Errno::ENOENT)
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
context 'with a valid command' do
|
|
198
|
-
it 'should execute command' do
|
|
199
|
-
expect(IO.popen('echo test').read.chomp).to eq('test')
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
context 'with a non blocked command present' do
|
|
204
|
-
context 'with no command injection' do
|
|
205
|
-
it 'should execute the command' do
|
|
206
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
207
|
-
TCellAgent::PolicyTypes::RUST
|
|
208
|
-
).and_return(nil)
|
|
209
|
-
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:cmdi_enabled)
|
|
210
|
-
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:block_command?)
|
|
211
|
-
|
|
212
|
-
IO.popen('echo test')
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
context 'with command injection disabled' do
|
|
217
|
-
it 'should execute the command' do
|
|
218
|
-
expect(@rust_policies.cmdi_enabled).to eq(false)
|
|
219
|
-
|
|
220
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
221
|
-
TCellAgent::PolicyTypes::RUST
|
|
222
|
-
).and_return(@rust_policies)
|
|
223
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_call_original
|
|
224
|
-
expect(@rust_policies).to_not receive(:block_command?)
|
|
225
|
-
|
|
226
|
-
IO.popen('echo test')
|
|
227
|
-
end
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
context 'with command injection enabled' do
|
|
231
|
-
it 'should execute the command' do
|
|
232
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
233
|
-
TCellAgent::PolicyTypes::RUST
|
|
234
|
-
).and_return(@rust_policies)
|
|
235
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
236
|
-
expect(@rust_policies).to receive(:block_command?).with('echo test', nil).and_return(false)
|
|
237
|
-
|
|
238
|
-
IO.popen('echo test')
|
|
239
|
-
end
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
context 'with a blocked command present' do
|
|
244
|
-
context 'with command injection enabled' do
|
|
245
|
-
it 'should raise a Errno::ENOENT' do
|
|
246
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
247
|
-
TCellAgent::PolicyTypes::RUST
|
|
248
|
-
).and_return(@rust_policies)
|
|
249
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
250
|
-
expect(@rust_policies).to receive(:block_command?).with('echo test', nil).and_return(true)
|
|
251
|
-
|
|
252
|
-
expect do
|
|
253
|
-
IO.popen('echo test')
|
|
254
|
-
end.to raise_error(Errno::ENOENT)
|
|
255
|
-
end
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
context 'with env' do
|
|
260
|
-
before(:each) do
|
|
261
|
-
@env = { 'TCELL_VAR' => 'enabled' }
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
context 'with string command' do
|
|
265
|
-
it 'should execute the command' do
|
|
266
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
267
|
-
IO.popen(@env, 'echo', 'w+')
|
|
268
|
-
|
|
269
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
270
|
-
IO.popen(@env, 'echo', 'w+', :unsetenv_others => true)
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
context 'with string command and arguments' do
|
|
275
|
-
it 'should parse the command' do
|
|
276
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
277
|
-
IO.popen(@env, 'echo test')
|
|
278
|
-
|
|
279
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
280
|
-
IO.popen(@env, 'echo test', 'w+')
|
|
281
|
-
|
|
282
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
283
|
-
IO.popen(@env, 'echo test', :unsetenv_others => true)
|
|
284
|
-
|
|
285
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
286
|
-
IO.popen(@env, 'echo test', 'w+', :unsetenv_others => true)
|
|
287
|
-
end
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
context 'with array command' do
|
|
291
|
-
it 'should parse the command properly' do
|
|
292
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
293
|
-
IO.popen(@env, [%w[echo argv0]], 'w+')
|
|
294
|
-
|
|
295
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
296
|
-
IO.popen(@env, [%w[echo argv0]], :unsetenv_others => true)
|
|
297
|
-
|
|
298
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
299
|
-
IO.popen(@env, [%w[echo argv0]], 'w+', :unsetenv_others => true)
|
|
300
|
-
|
|
301
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
302
|
-
IO.popen(@env, ['echo'], 'w+')
|
|
303
|
-
|
|
304
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
305
|
-
IO.popen(@env, ['echo'], :unsetenv_others => true)
|
|
306
|
-
|
|
307
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo')
|
|
308
|
-
IO.popen(@env, ['echo'], 'w+', :unsetenv_others => true)
|
|
309
|
-
end
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
context 'with array command and arguments' do
|
|
313
|
-
it 'should parse the command properly' do
|
|
314
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
315
|
-
IO.popen(@env, [%w[echo argv0], 'test'])
|
|
316
|
-
|
|
317
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
318
|
-
IO.popen(@env, [%w[echo argv0], 'test'], 'w+')
|
|
319
|
-
|
|
320
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
321
|
-
IO.popen(@env, [%w[echo argv0], 'test'], :unsetenv_others => true)
|
|
322
|
-
|
|
323
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
324
|
-
IO.popen(@env, [%w[echo argv0], 'test'], 'w+', :unsetenv_others => true)
|
|
325
|
-
|
|
326
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
327
|
-
IO.popen(@env, %w[echo test])
|
|
328
|
-
|
|
329
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
330
|
-
IO.popen(@env, %w[echo test], 'w+')
|
|
331
|
-
|
|
332
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
333
|
-
IO.popen(@env, %w[echo test], :unsetenv_others => true)
|
|
334
|
-
|
|
335
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
336
|
-
IO.popen(@env, %w[echo test], 'w+', :unsetenv_others => true)
|
|
337
|
-
|
|
338
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
339
|
-
IO.popen([@env, 'echo', 'test', :unsetenv_others => true], 'w+')
|
|
340
|
-
|
|
341
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
342
|
-
IO.popen(@env, [@env, 'echo', 'test', :unsetenv_others => true], 'w+', :err => %i[child out])
|
|
343
|
-
end
|
|
344
|
-
end
|
|
345
|
-
end
|
|
346
|
-
|
|
347
|
-
context 'without env' do
|
|
348
|
-
context 'with array command and arguments' do
|
|
349
|
-
it 'should parse the command properly' do
|
|
350
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
351
|
-
IO.popen([%w[echo argv0], 'test'])
|
|
352
|
-
|
|
353
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
354
|
-
IO.popen([%w[echo argv0], 'test'], 'w+')
|
|
355
|
-
|
|
356
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
357
|
-
IO.popen([%w[echo argv0], 'test'], :unsetenv_others => true)
|
|
358
|
-
|
|
359
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
360
|
-
IO.popen([%w[echo argv0], 'test'], 'w+', :unsetenv_others => true)
|
|
361
|
-
|
|
362
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
363
|
-
IO.popen(%w[echo test])
|
|
364
|
-
|
|
365
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
366
|
-
IO.popen(%w[echo test], 'w+')
|
|
367
|
-
|
|
368
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
369
|
-
IO.popen(%w[echo test], :unsetenv_others => true)
|
|
370
|
-
|
|
371
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with('echo test')
|
|
372
|
-
IO.popen(%w[echo test], 'w+', :unsetenv_others => true)
|
|
373
|
-
|
|
374
|
-
expect(TCellAgent::Cmdi).to receive(:block_command?).with(
|
|
375
|
-
"echo -size 320x85 canvas:none -font Bookman-DemiItalic -draw \"text 25,60 'Magick'\""
|
|
376
|
-
)
|
|
377
|
-
IO.popen(
|
|
378
|
-
[%w[echo argv0],
|
|
379
|
-
'-size',
|
|
380
|
-
'320x85',
|
|
381
|
-
'canvas:none',
|
|
382
|
-
'-font',
|
|
383
|
-
'Bookman-DemiItalic',
|
|
384
|
-
'-draw',
|
|
385
|
-
"\"text 25,60 \'Magick\'\""],
|
|
386
|
-
:unsetenv_others => true
|
|
387
|
-
)
|
|
388
|
-
end
|
|
389
|
-
end
|
|
390
|
-
end
|
|
391
|
-
end
|
|
392
|
-
end
|
|
393
|
-
|
|
394
|
-
describe Kernel do
|
|
395
|
-
before(:each) do
|
|
396
|
-
configuration = double(
|
|
397
|
-
'configuration',
|
|
398
|
-
{
|
|
399
|
-
'app_id' => 'app_id',
|
|
400
|
-
'api_key' => 'api_key',
|
|
401
|
-
'allow_payloads' => true,
|
|
402
|
-
'js_agent_api_base_url' => 'http://api.tcell.com/',
|
|
403
|
-
'js_agent_url' => 'https://jsagent.tcell.io/tcellagent.min.js',
|
|
404
|
-
'max_csp_header_bytes' => nil,
|
|
405
|
-
'event_time_limit_seconds' => 15,
|
|
406
|
-
'event_batch_size_limit' => 50,
|
|
407
|
-
'preload_policy_filename' => nil,
|
|
408
|
-
'cache_filename_with_app_id' => '/tcellagent_src/tcell/cache/tcell_agent.cache',
|
|
409
|
-
'agent_home_owner' => nil
|
|
410
|
-
}
|
|
411
|
-
)
|
|
412
|
-
expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
|
|
413
|
-
@rust_policies = TCellAgent::Policies::RustPolicies.new
|
|
414
|
-
end
|
|
415
|
-
|
|
416
|
-
describe '.backtick' do
|
|
417
|
-
context 'empty command' do
|
|
418
|
-
it 'should raise Errno::ENOENT' do
|
|
419
|
-
expect do
|
|
420
|
-
``
|
|
421
|
-
end.to raise_error(Errno::ENOENT)
|
|
422
|
-
end
|
|
423
|
-
end
|
|
424
|
-
|
|
425
|
-
context 'with a non blocked command present' do
|
|
426
|
-
context 'with no command injection' do
|
|
427
|
-
it 'should execute the command' do
|
|
428
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
429
|
-
TCellAgent::PolicyTypes::RUST
|
|
430
|
-
).and_return(nil)
|
|
431
|
-
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:cmdi_enabled)
|
|
432
|
-
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:block_command?)
|
|
433
|
-
|
|
434
|
-
`echo test`
|
|
435
|
-
end
|
|
436
|
-
end
|
|
437
|
-
|
|
438
|
-
context 'with command injection disabled' do
|
|
439
|
-
it 'should execute the command' do
|
|
440
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
441
|
-
TCellAgent::PolicyTypes::RUST
|
|
442
|
-
).and_return(@rust_policies)
|
|
443
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(false)
|
|
444
|
-
expect(@rust_policies).to_not receive(:block_command?)
|
|
445
|
-
|
|
446
|
-
`echo test`
|
|
447
|
-
end
|
|
448
|
-
end
|
|
449
|
-
|
|
450
|
-
context 'with command injection enabled' do
|
|
451
|
-
it 'should execute the command' do
|
|
452
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
453
|
-
TCellAgent::PolicyTypes::RUST
|
|
454
|
-
).and_return(@rust_policies)
|
|
455
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
456
|
-
expect(@rust_policies).to receive(:block_command?).with('echo test', nil).and_return(false)
|
|
457
|
-
|
|
458
|
-
`echo test`
|
|
459
|
-
end
|
|
460
|
-
end
|
|
461
|
-
end
|
|
462
|
-
|
|
463
|
-
context 'with a blocked command present' do
|
|
464
|
-
context 'with command injection enabled' do
|
|
465
|
-
it 'should raise a Errno::ENOENT' do
|
|
466
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
467
|
-
TCellAgent::PolicyTypes::RUST
|
|
468
|
-
).and_return(@rust_policies)
|
|
469
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
470
|
-
expect(@rust_policies).to receive(:block_command?).with('echo test', nil).and_return(true)
|
|
471
|
-
|
|
472
|
-
expect do
|
|
473
|
-
`echo test`
|
|
474
|
-
end.to raise_error(Errno::ENOENT)
|
|
475
|
-
end
|
|
476
|
-
end
|
|
477
|
-
end
|
|
478
|
-
end
|
|
479
|
-
|
|
480
|
-
describe '%x methods' do
|
|
481
|
-
context 'empty command' do
|
|
482
|
-
it 'should raise Errno::ENOENT' do
|
|
483
|
-
expect do
|
|
484
|
-
``
|
|
485
|
-
end.to raise_error(Errno::ENOENT)
|
|
486
|
-
end
|
|
487
|
-
end
|
|
488
|
-
|
|
489
|
-
context 'with a non blocked command present' do
|
|
490
|
-
context 'with no command injection' do
|
|
491
|
-
it 'should execute the command' do
|
|
492
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
493
|
-
TCellAgent::PolicyTypes::RUST
|
|
494
|
-
).and_return(nil)
|
|
495
|
-
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:cmdi_enabled)
|
|
496
|
-
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:block_command?)
|
|
497
|
-
|
|
498
|
-
`echo test`
|
|
499
|
-
end
|
|
500
|
-
end
|
|
501
|
-
|
|
502
|
-
context 'with command injection disabled' do
|
|
503
|
-
it 'should execute the command' do
|
|
504
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
505
|
-
TCellAgent::PolicyTypes::RUST
|
|
506
|
-
).and_return(@rust_policies)
|
|
507
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(false)
|
|
508
|
-
expect(@rust_policies).to_not receive(:block_command?)
|
|
509
|
-
|
|
510
|
-
`echo test`
|
|
511
|
-
end
|
|
512
|
-
end
|
|
513
|
-
|
|
514
|
-
context 'with command injection enabled' do
|
|
515
|
-
it 'should execute the command' do
|
|
516
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
517
|
-
TCellAgent::PolicyTypes::RUST
|
|
518
|
-
).and_return(@rust_policies)
|
|
519
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
520
|
-
expect(@rust_policies).to receive(:block_command?).with('echo test', nil).and_return(false)
|
|
521
|
-
|
|
522
|
-
`echo test`
|
|
523
|
-
end
|
|
524
|
-
end
|
|
525
|
-
end
|
|
526
|
-
|
|
527
|
-
context 'with a blocked command present' do
|
|
528
|
-
context 'with command injection enabled' do
|
|
529
|
-
it 'should raise a Errno::ENOENT' do
|
|
530
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
531
|
-
TCellAgent::PolicyTypes::RUST
|
|
532
|
-
).and_return(@rust_policies)
|
|
533
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
534
|
-
expect(@rust_policies).to receive(:block_command?).with('echo test', nil).and_return(true)
|
|
535
|
-
|
|
536
|
-
expect do
|
|
537
|
-
`echo test`
|
|
538
|
-
end.to raise_error(Errno::ENOENT)
|
|
539
|
-
end
|
|
540
|
-
end
|
|
541
|
-
end
|
|
542
|
-
end
|
|
543
|
-
|
|
544
|
-
describe '.system' do
|
|
545
|
-
context 'empty command' do
|
|
546
|
-
it 'should raise an error' do
|
|
547
|
-
expect do
|
|
548
|
-
system
|
|
549
|
-
end.to raise_error(ArgumentError)
|
|
550
|
-
expect do
|
|
551
|
-
system(nil)
|
|
552
|
-
end.to raise_error(TypeError)
|
|
553
|
-
|
|
554
|
-
expect(system('')).to be_nil
|
|
555
|
-
end
|
|
556
|
-
end
|
|
557
|
-
|
|
558
|
-
context 'non existent command' do
|
|
559
|
-
it 'should return nil' do
|
|
560
|
-
expect(system('foobar')).to be_nil
|
|
561
|
-
end
|
|
562
|
-
end
|
|
563
|
-
|
|
564
|
-
context 'with a valid command' do
|
|
565
|
-
it 'should execute command' do
|
|
566
|
-
pid = system('echo test > /dev/null 2>&1')
|
|
567
|
-
expect(pid).to eq(true)
|
|
568
|
-
|
|
569
|
-
pid = system(RbConfig.ruby, "-e'Hello World!'", '>', '/dev/null', '2>&1')
|
|
570
|
-
expect(pid).to eq(true)
|
|
571
|
-
end
|
|
572
|
-
end
|
|
573
|
-
|
|
574
|
-
context 'with a non blocked command present' do
|
|
575
|
-
context 'with no command injection' do
|
|
576
|
-
it 'should execute the command' do
|
|
577
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
578
|
-
TCellAgent::PolicyTypes::RUST
|
|
579
|
-
).and_return(nil)
|
|
580
|
-
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:cmdi_enabled)
|
|
581
|
-
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:block_command?)
|
|
582
|
-
|
|
583
|
-
system('echo test > /dev/null 2>&1')
|
|
584
|
-
end
|
|
585
|
-
end
|
|
586
|
-
|
|
587
|
-
context 'with command injection disabled' do
|
|
588
|
-
it 'should execute the command' do
|
|
589
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
590
|
-
TCellAgent::PolicyTypes::RUST
|
|
591
|
-
).and_return(@rust_policies)
|
|
592
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(false)
|
|
593
|
-
expect(@rust_policies).to_not receive(:block_command?)
|
|
594
|
-
|
|
595
|
-
system('echo test > /dev/null 2>&1')
|
|
596
|
-
end
|
|
597
|
-
end
|
|
598
|
-
|
|
599
|
-
context 'with command injection enabled' do
|
|
600
|
-
it 'should execute the command' do
|
|
601
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
602
|
-
TCellAgent::PolicyTypes::RUST
|
|
603
|
-
).and_return(@rust_policies)
|
|
604
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
605
|
-
expect(@rust_policies).to receive(:block_command?).with('echo test > /dev/null 2>&1', nil).and_return(false)
|
|
606
|
-
|
|
607
|
-
system('echo test > /dev/null 2>&1')
|
|
608
|
-
end
|
|
609
|
-
end
|
|
610
|
-
end
|
|
611
|
-
|
|
612
|
-
context 'with a blocked command present' do
|
|
613
|
-
context 'with command injection enabled' do
|
|
614
|
-
it 'should raise a Errno::ENOENT' do
|
|
615
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
616
|
-
TCellAgent::PolicyTypes::RUST
|
|
617
|
-
).and_return(@rust_policies)
|
|
618
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
619
|
-
expect(@rust_policies).to receive(:block_command?).with('echo test', nil).and_return(true)
|
|
620
|
-
|
|
621
|
-
expect do
|
|
622
|
-
system('echo test')
|
|
623
|
-
end.to raise_error(Errno::ENOENT)
|
|
624
|
-
end
|
|
625
|
-
end
|
|
626
|
-
end
|
|
627
|
-
end
|
|
628
|
-
|
|
629
|
-
describe '.spawn' do
|
|
630
|
-
context 'empty command' do
|
|
631
|
-
it 'should raise an error' do
|
|
632
|
-
expect do
|
|
633
|
-
spawn
|
|
634
|
-
end.to raise_error(ArgumentError)
|
|
635
|
-
expect do
|
|
636
|
-
spawn(nil)
|
|
637
|
-
end.to raise_error(TypeError)
|
|
638
|
-
expect do
|
|
639
|
-
spawn('')
|
|
640
|
-
end.to raise_error(Errno::ENOENT)
|
|
641
|
-
end
|
|
642
|
-
end
|
|
643
|
-
|
|
644
|
-
context 'non existent command' do
|
|
645
|
-
it 'should raise error' do
|
|
646
|
-
expect do
|
|
647
|
-
spawn('foobar')
|
|
648
|
-
end.to raise_error(Errno::ENOENT)
|
|
649
|
-
end
|
|
650
|
-
end
|
|
651
|
-
|
|
652
|
-
context 'with a valid command' do
|
|
653
|
-
it 'should execute command' do
|
|
654
|
-
pid = spawn('echo test > /dev/null 2>&1')
|
|
655
|
-
expect(pid).to_not be_nil
|
|
656
|
-
|
|
657
|
-
pid = spawn(RbConfig.ruby, "-e'Hello World!'", '>', '/dev/null', '2>&1')
|
|
658
|
-
expect(pid).to_not be_nil
|
|
659
|
-
end
|
|
660
|
-
end
|
|
661
|
-
|
|
662
|
-
context 'with a non blocked command present' do
|
|
663
|
-
context 'with no command injection' do
|
|
664
|
-
it 'should execute the command' do
|
|
665
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
666
|
-
TCellAgent::PolicyTypes::RUST
|
|
667
|
-
).and_return(nil)
|
|
668
|
-
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:cmdi_enabled)
|
|
669
|
-
expect_any_instance_of(TCellAgent::Policies::RustPolicies).to_not receive(:block_command?)
|
|
670
|
-
|
|
671
|
-
spawn('echo test > /dev/null 2>&1')
|
|
672
|
-
end
|
|
673
|
-
end
|
|
674
|
-
|
|
675
|
-
context 'with command injection disabled' do
|
|
676
|
-
it 'should execute the command' do
|
|
677
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
678
|
-
TCellAgent::PolicyTypes::RUST
|
|
679
|
-
).and_return(@rust_policies)
|
|
680
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(false)
|
|
681
|
-
expect(@rust_policies).to_not receive(:block_command?)
|
|
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
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
690
|
-
TCellAgent::PolicyTypes::RUST
|
|
691
|
-
).and_return(@rust_policies)
|
|
692
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
693
|
-
expect(@rust_policies).to receive(:block_command?).with('echo test > /dev/null 2>&1', nil).and_return(false)
|
|
694
|
-
|
|
695
|
-
spawn('echo test > /dev/null 2>&1')
|
|
696
|
-
end
|
|
697
|
-
end
|
|
698
|
-
end
|
|
699
|
-
|
|
700
|
-
context 'with a blocked command present' do
|
|
701
|
-
context 'with command injection enabled' do
|
|
702
|
-
it 'should raise a Errno::ENOENT' do
|
|
703
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
704
|
-
TCellAgent::PolicyTypes::RUST
|
|
705
|
-
).and_return(@rust_policies)
|
|
706
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
707
|
-
expect(@rust_policies).to receive(:block_command?).with('echo test', nil).and_return(true)
|
|
708
|
-
|
|
709
|
-
expect do
|
|
710
|
-
spawn('echo test')
|
|
711
|
-
end.to raise_error(Errno::ENOENT)
|
|
712
|
-
end
|
|
713
|
-
end
|
|
714
|
-
end
|
|
715
|
-
end
|
|
716
|
-
|
|
717
|
-
describe '.exec' do
|
|
718
|
-
# can only test this case since exec replaces current process with new process
|
|
719
|
-
context 'with a blocked command present' do
|
|
720
|
-
context 'with command injection enabled' do
|
|
721
|
-
it 'should raise a Errno::ENOENT' do
|
|
722
|
-
expect(TCellAgent).to receive(:policy).with(
|
|
723
|
-
TCellAgent::PolicyTypes::RUST
|
|
724
|
-
).and_return(@rust_policies)
|
|
725
|
-
expect(@rust_policies).to receive(:cmdi_enabled).and_return(true)
|
|
726
|
-
expect(@rust_policies).to receive(:block_command?).with('echo test', nil).and_return(true)
|
|
727
|
-
|
|
728
|
-
expect do
|
|
729
|
-
exec('echo test')
|
|
730
|
-
end.to raise_error(Errno::ENOENT)
|
|
731
|
-
end
|
|
732
|
-
end
|
|
733
|
-
end
|
|
734
|
-
end
|
|
735
|
-
end
|
|
736
|
-
end
|