tcell_agent 1.1.11 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/bin/tcell_agent +26 -14
  3. data/lib/tcell_agent.rb +16 -10
  4. data/lib/tcell_agent/agent.rb +78 -97
  5. data/lib/tcell_agent/agent/route_manager.rb +0 -16
  6. data/lib/tcell_agent/agent/static_agent.rb +9 -30
  7. data/lib/tcell_agent/authlogic.rb +3 -6
  8. data/lib/tcell_agent/config/unknown_options.rb +4 -7
  9. data/lib/tcell_agent/configuration.rb +39 -118
  10. data/lib/tcell_agent/devise.rb +25 -27
  11. data/lib/tcell_agent/hooks/login_fraud.rb +30 -33
  12. data/lib/tcell_agent/instrument_servers.rb +25 -0
  13. data/lib/tcell_agent/instrumentation.rb +12 -10
  14. data/lib/tcell_agent/instrumentation/cmdi.rb +29 -25
  15. data/lib/tcell_agent/instrumentation/lfi.rb +84 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +25 -0
  17. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +131 -0
  18. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +102 -0
  19. data/lib/tcell_agent/logger.rb +50 -114
  20. data/lib/tcell_agent/patches.rb +6 -7
  21. data/lib/tcell_agent/policies/appfirewall_policy.rb +26 -0
  22. data/lib/tcell_agent/policies/command_injection_policy.rb +28 -0
  23. data/lib/tcell_agent/policies/dataloss_policy.rb +44 -44
  24. data/lib/tcell_agent/policies/headers_policy.rb +25 -0
  25. data/lib/tcell_agent/policies/http_redirect_policy.rb +13 -79
  26. data/lib/tcell_agent/policies/js_agent_policy.rb +27 -0
  27. data/lib/tcell_agent/policies/local_file_access.rb +28 -0
  28. data/lib/tcell_agent/policies/login_policy.rb +43 -0
  29. data/lib/tcell_agent/policies/patches_policy.rb +27 -0
  30. data/lib/tcell_agent/policies/policies_manager.rb +68 -0
  31. data/lib/tcell_agent/policies/policy_polling.rb +58 -0
  32. data/lib/tcell_agent/policies/policy_types.rb +14 -0
  33. data/lib/tcell_agent/policies/system_enablements.rb +27 -0
  34. data/lib/tcell_agent/rails/auth/authlogic.rb +43 -68
  35. data/lib/tcell_agent/rails/auth/devise.rb +20 -23
  36. data/lib/tcell_agent/rails/auth/doorkeeper.rb +63 -74
  37. data/lib/tcell_agent/rails/csrf_exception.rb +2 -2
  38. data/lib/tcell_agent/rails/dlp.rb +35 -19
  39. data/lib/tcell_agent/rails/dlp_handler.rb +1 -2
  40. data/lib/tcell_agent/rails/js_agent_insert.rb +12 -13
  41. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +4 -25
  42. data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -12
  43. data/lib/tcell_agent/rails/middleware/global_middleware.rb +0 -1
  44. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +14 -34
  45. data/lib/tcell_agent/rails/on_start.rb +32 -31
  46. data/lib/tcell_agent/rails/routes.rb +10 -9
  47. data/lib/tcell_agent/rails/routes/grape.rb +4 -12
  48. data/lib/tcell_agent/rails/routes/route_id.rb +3 -1
  49. data/lib/tcell_agent/rails/settings_reporter.rb +23 -36
  50. data/lib/tcell_agent/rails/start_agent_after_initializers.rb +12 -0
  51. data/lib/tcell_agent/rails/tcell_body_proxy.rb +6 -4
  52. data/lib/tcell_agent/rust/agent_config.rb +49 -0
  53. data/lib/tcell_agent/rust/{libtcellagent-alpine-1.3.2.so → libtcellagent-4.18.0.dylib} +0 -0
  54. data/lib/tcell_agent/rust/{libtcellagent-1.3.2.so → libtcellagent-4.18.0.so} +0 -0
  55. data/lib/tcell_agent/rust/libtcellagent-alpine-4.18.0.so +0 -0
  56. data/lib/tcell_agent/rust/models.rb +0 -55
  57. data/lib/tcell_agent/rust/native_agent.rb +531 -0
  58. data/lib/tcell_agent/rust/native_agent_response.rb +42 -0
  59. data/lib/tcell_agent/rust/native_library.rb +68 -0
  60. data/lib/tcell_agent/rust/tcellagent-4.18.0.dll +0 -0
  61. data/lib/tcell_agent/sensor_events/agent_setting_event.rb +12 -0
  62. data/lib/tcell_agent/sensor_events/{app_config.rb → app_config_setting_event.rb} +0 -6
  63. data/lib/tcell_agent/sensor_events/dlp.rb +2 -6
  64. data/lib/tcell_agent/sensor_events/sensor.rb +0 -62
  65. data/lib/tcell_agent/sensor_events/server_agent.rb +13 -18
  66. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +0 -108
  67. data/lib/tcell_agent/sensor_events/util/utils.rb +0 -2
  68. data/lib/tcell_agent/servers/passenger.rb +1 -28
  69. data/lib/tcell_agent/servers/puma.rb +3 -21
  70. data/lib/tcell_agent/servers/rails_server.rb +1 -1
  71. data/lib/tcell_agent/servers/thin.rb +2 -2
  72. data/lib/tcell_agent/servers/unicorn.rb +19 -80
  73. data/lib/tcell_agent/servers/webrick.rb +1 -1
  74. data/lib/tcell_agent/settings_reporter.rb +24 -24
  75. data/lib/tcell_agent/sinatra.rb +14 -16
  76. data/lib/tcell_agent/tcell_context.rb +41 -15
  77. data/lib/tcell_agent/utils/headers.rb +14 -0
  78. data/lib/tcell_agent/version.rb +1 -1
  79. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -18
  80. data/spec/lib/tcell_agent/configuration_spec.rb +4 -140
  81. data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +46 -173
  82. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +504 -0
  83. data/spec/lib/tcell_agent/instrumentation/cmdi/kernel_cmdi_spec.rb +435 -0
  84. data/spec/lib/tcell_agent/instrumentation/cmdi_spec.rb +201 -0
  85. data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +326 -0
  86. data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +562 -0
  87. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +264 -0
  88. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +150 -0
  89. data/spec/lib/tcell_agent/patches_spec.rb +25 -43
  90. data/spec/lib/tcell_agent/policies/appfirewall_policy_spec.rb +183 -0
  91. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +57 -0
  92. data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +84 -773
  93. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +161 -0
  94. data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +9 -9
  95. data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +243 -198
  96. data/spec/lib/tcell_agent/policies/js_agent_policy_spec.rb +75 -0
  97. data/spec/lib/tcell_agent/policies/login_policy_spec.rb +165 -33
  98. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +84 -277
  99. data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +104 -0
  100. data/spec/lib/tcell_agent/policies/policy_polling_spec.rb +6 -0
  101. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +56 -0
  102. data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +9 -18
  103. data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +13 -30
  104. data/spec/lib/tcell_agent/rails/logger_spec.rb +27 -7
  105. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +17 -12
  106. data/spec/lib/tcell_agent/rails/routes/routes_spec.rb +14 -14
  107. data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +0 -35
  108. data/spec/lib/tcell_agent/settings_reporter_spec.rb +127 -153
  109. data/spec/spec_helper.rb +1 -1
  110. data/spec/support/builders.rb +104 -0
  111. data/spec/support/force_logger_mocking.rb +38 -0
  112. data/spec/support/resources/lfi_sample_file.txt +2 -0
  113. data/spec/support/static_agent_overrides.rb +0 -15
  114. metadata +64 -74
  115. data/lib/tcell_agent/agent/event_processor.rb +0 -326
  116. data/lib/tcell_agent/agent/fork_pipe_manager.rb +0 -113
  117. data/lib/tcell_agent/agent/policy_manager.rb +0 -219
  118. data/lib/tcell_agent/agent/policy_types.rb +0 -30
  119. data/lib/tcell_agent/api.rb +0 -91
  120. data/lib/tcell_agent/appsensor/injections_reporter.rb +0 -24
  121. data/lib/tcell_agent/config/child_process_events.rb +0 -8
  122. data/lib/tcell_agent/instrumentation/cmdi/backtick.rb +0 -10
  123. data/lib/tcell_agent/instrumentation/cmdi/exec.rb +0 -14
  124. data/lib/tcell_agent/instrumentation/cmdi/popen.rb +0 -28
  125. data/lib/tcell_agent/instrumentation/cmdi/spawn.rb +0 -11
  126. data/lib/tcell_agent/instrumentation/cmdi/system.rb +0 -11
  127. data/lib/tcell_agent/policies/http_tx_policy.rb +0 -60
  128. data/lib/tcell_agent/policies/login_fraud_policy.rb +0 -45
  129. data/lib/tcell_agent/policies/rust_policies.rb +0 -110
  130. data/lib/tcell_agent/rails.rb +0 -40
  131. data/lib/tcell_agent/rust/libtcellagent-1.3.2.dylib +0 -0
  132. data/lib/tcell_agent/rust/tcellagent-1.3.2.dll +0 -0
  133. data/lib/tcell_agent/rust/whisperer.rb +0 -308
  134. data/lib/tcell_agent/sensor_events/appsensor_event.rb +0 -52
  135. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +0 -45
  136. data/lib/tcell_agent/sensor_events/command_injection.rb +0 -75
  137. data/lib/tcell_agent/sensor_events/honeytokens.rb +0 -16
  138. data/lib/tcell_agent/sensor_events/login_fraud.rb +0 -60
  139. data/lib/tcell_agent/sensor_events/metrics.rb +0 -123
  140. data/lib/tcell_agent/sensor_events/patches.rb +0 -21
  141. data/lib/tcell_agent/start_background_thread.rb +0 -55
  142. data/lib/tcell_agent/system_info.rb +0 -11
  143. data/lib/tcell_agent/utils/io.rb +0 -38
  144. data/lib/tcell_agent/utils/passwords.rb +0 -28
  145. data/lib/tcell_agent/utils/queue_with_timeout.rb +0 -142
  146. data/spec/lib/tcell_agent/agent/fork_pipe_manager_spec.rb +0 -100
  147. data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +0 -535
  148. data/spec/lib/tcell_agent/agent/static_agent_spec.rb +0 -133
  149. data/spec/lib/tcell_agent/api/api_spec.rb +0 -39
  150. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +0 -187
  151. data/spec/lib/tcell_agent/cmdi_spec.rb +0 -736
  152. data/spec/lib/tcell_agent/instrumentation_spec.rb +0 -225
  153. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +0 -517
  154. data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +0 -22
  155. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +0 -293
  156. data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +0 -198
  157. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +0 -180
  158. data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +0 -116
  159. data/spec/lib/tcell_agent/rust/models_spec.rb +0 -120
  160. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +0 -704
  161. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +0 -45
  162. data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +0 -272
  163. data/spec/lib/tcell_agent/utils/bounded_queue_spec.rb +0 -52
  164. data/spec/lib/tcell_agent/utils/passwords_spec.rb +0 -143
@@ -1,180 +0,0 @@
1
- require 'spec_helper'
2
- require 'rack/test'
3
- require 'rack'
4
-
5
- module TCellAgent
6
- module Instrumentation
7
- module Rails
8
- module Middleware
9
- class MockRackApp
10
- attr_reader :request_body
11
-
12
- def initialize
13
- @request_headers = {}
14
- end
15
-
16
- def call(env)
17
- @env = env
18
- @request_body = env['rack.input'].read
19
- rack_request = Rack::Request.new(env)
20
- response_headers = { 'Content-Type' => 'text/html' }
21
- if rack_request.params['rv']
22
- response_headers['Location'] = rack_request.params['rv']
23
- end
24
- [200, response_headers, ['OK']]
25
- end
26
-
27
- def [](key)
28
- @env[key]
29
- end
30
- end
31
-
32
- describe HeadersMiddleware do
33
- let(:app) { MockRackApp.new }
34
- subject { with_tcell_middleware(app) }
35
-
36
- context 'Redirect Middleware' do
37
- let(:request) { Rack::MockRequest.new(subject) }
38
- let(:agent) { ::TCellAgent::Agent.new(Process.pid) }
39
- before(:each) do
40
- TCellAgent.configuration = TCellAgent::Configuration.new
41
- TCellAgent.configuration.read_config_from_file(get_test_resource_path('normal_config.json'))
42
-
43
- # avoid running start_policy_polling for these specs
44
- expect(agent).to receive(:start_policy_polling_loop).at_most(50)
45
-
46
- agent.start
47
- TCellAgent.thread_agent = agent
48
- end
49
-
50
- context 'not enabled' do
51
- it 'passes through unchanged' do
52
- agent.process_policy_json(
53
- {
54
- 'http-redirect' => {
55
- 'policy_id' => '153ed270-7481-11e5-9194-95dad9b9dec3',
56
- 'data' => {
57
- 'enabled' => false,
58
- 'block' => true,
59
- 'whitelist' => []
60
- }
61
- }
62
- },
63
- false
64
- )
65
- response = request.get('/some/path?rv=https://www.google.com', 'CONTENT_TYPE' => 'text/html')
66
- expect(response['Location']).to eq('https://www.google.com')
67
- end
68
- end
69
-
70
- context "doesn't block simple whitelist" do
71
- it 'passes through unchanged' do
72
- agent.process_policy_json(
73
- {
74
- 'http-redirect' => {
75
- 'policy_id' => '153ed270-7481-11e5-9194-95dad9b9dec3',
76
- 'data' => {
77
- 'enabled' => true,
78
- 'block' => true,
79
- 'whitelist' => ['www.google.com']
80
- }
81
- }
82
- },
83
- false
84
- )
85
-
86
- response = request.get('/some/path?rv=https://www.google.com', 'CONTENT_TYPE' => 'text/html')
87
- expect(response['Location']).to eq('https://www.google.com')
88
- end
89
- end
90
-
91
- context "doesn't block wildcard whitelist" do
92
- it 'passes through unchanged' do
93
- agent.process_policy_json(
94
- {
95
- 'http-redirect' => {
96
- 'policy_id' => '153ed270-7481-11e5-9194-95dad9b9dec3',
97
- 'data' => {
98
- 'enabled' => true,
99
- 'block' => true,
100
- 'whitelist' => ['*.google.com']
101
- }
102
- }
103
- },
104
- false
105
- )
106
- response = request.get('/some/path?rv=https://www.google.com', 'CONTENT_TYPE' => 'text/html')
107
- expect(response['Location']).to eq('https://www.google.com')
108
- end
109
- end
110
-
111
- context 'DOES block wildcard whitelist' do
112
- it 'replaces the value with /' do
113
- agent.process_policy_json(
114
- {
115
- 'http-redirect' => {
116
- 'policy_id' => '153ed270-7481-11e5-9194-95dad9b9dec3',
117
- 'data' => {
118
- 'enabled' => true,
119
- 'block' => true,
120
- 'whitelist' => ['*.google-test.com']
121
- }
122
- }
123
- },
124
- false
125
- )
126
-
127
- response = request.get('/some/path?rv=https://www.google.com', 'CONTENT_TYPE' => 'text/html')
128
- expect(response['Location']).to eq('/')
129
- end
130
- end
131
- end
132
-
133
- context 'CSP Middleware' do
134
- let(:request) { Rack::MockRequest.new(subject) }
135
- let(:agent) { ::TCellAgent::Agent.new(Process.pid) }
136
-
137
- before(:each) do
138
- TCellAgent.configuration = TCellAgent::Configuration.new
139
- TCellAgent.configuration.read_config_from_file(get_test_resource_path('normal_config.json'))
140
-
141
- # avoid running start_policy_polling for these specs
142
- expect(agent).to receive(:start_policy_polling_loop).at_most(50)
143
-
144
- agent.start
145
- TCellAgent.thread_agent = agent
146
- end
147
-
148
- context 'Standard CSP Header' do
149
- it 'CSP Header is Added' do
150
- agent.process_policy_json(
151
- {
152
- 'csp-headers' => {
153
- 'policy_id' => '153ed270-7481-11e5-9194-95dad9b9dec3',
154
- 'headers' => [
155
- {
156
- 'name' => 'Content-Security-Policy-Report-Only',
157
- 'value' => "script-src 'unsafe-inline'",
158
- 'report_uri' => 'http://test.tcell.io/report'
159
- }
160
- ]
161
- }
162
- },
163
- false
164
- )
165
- response = request.get(
166
- '/some/path',
167
- 'CONTENT_TYPE' => 'text/plain',
168
- 'action_dispatch.request_id' => '35281717-247e-44e6-bd42-0fb1417e80d'
169
- )
170
- expect(response['Content-Security-Policy-Report-Only']).to eq(
171
- "script-src 'unsafe-inline'; report-uri http://test.tcell.io/report"
172
- )
173
- end
174
- end
175
- end
176
- end
177
- end
178
- end
179
- end
180
- end
@@ -1,116 +0,0 @@
1
- require 'spec_helper'
2
- require 'rack/test'
3
- require 'rack'
4
-
5
- module TCellAgent
6
- module Instrumentation
7
- module Rails
8
- module Middleware
9
- class MockAppsensorRackApp
10
- attr_reader :request_body
11
-
12
- def initialize(route_id = nil, hmac_session_id = nil)
13
- @route_id = route_id
14
- @hmac_session_id = hmac_session_id
15
- @request_headers = {}
16
- end
17
-
18
- def call(env)
19
- @env = env
20
- rack_request = Rack::Request.new(env)
21
- response_headers = { 'Content-Type' => 'text/html' }
22
- env['tcell.request_data'].transaction_id = 'a-b-c-d-e-f'
23
- env['tcell.request_data'].hmac_session_id = @hmac_session_id
24
- env['tcell.request_data'].route_id = @route_id
25
- if rack_request.params['rv']
26
- response_headers['Location'] = rack_request.params['rv']
27
- end
28
- [200, response_headers, ['OK']]
29
- end
30
-
31
- def [](key)
32
- @env[key]
33
- end
34
- end
35
-
36
- describe HeadersMiddleware do
37
- let(:app) { MockAppsensorRackApp.new }
38
- let(:app2) { MockAppsensorRackApp.new('myrouteid', 'hmac_sessionid') }
39
-
40
- subject { with_tcell_middleware(app) }
41
-
42
- context 'Redirect Middleware' do
43
- before(:each) do
44
- TCellAgent.configuration = TCellAgent::Configuration.new
45
- TCellAgent.configuration.read_config_from_file(get_test_resource_path('normal_config.json'))
46
- end
47
-
48
- let(:request) { Rack::MockRequest.new(subject) }
49
- let(:request2) { Rack::MockRequest.new(with_tcell_middleware(app2)) }
50
- let(:agent) { ::TCellAgent::Agent.new }
51
-
52
- context 'Event' do
53
- before(:each) do
54
- TCellAgent.thread_agent.process_policy_json(
55
- {
56
- 'http-redirect' =>
57
- {
58
- 'policy_id' => '153ed270-7481-11e5-9194-95dad9b9dec3',
59
- 'data' => {
60
- 'enabled' => true,
61
- 'block' => false,
62
- 'whitelist' => []
63
- }
64
- }
65
- },
66
- false
67
- )
68
- TCellAgent.empty_event_queue
69
- end
70
-
71
- it 'sends redirect' do
72
- response = request.get(
73
- '/some/path2?abcdef=adsfsadf&rv=https://www.google.com',
74
- 'CONTENT_TYPE' => 'text/html',
75
- 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6'
76
- )
77
- expect(response['Location']).to eq('https://www.google.com')
78
- expected_as = {
79
- 'event_type' => 'redirect',
80
- 'method' => 'GET',
81
- 'from_domain' => 'example.org',
82
- 'status_code' => 200,
83
- 'remote_addr' => '1.3.3.4',
84
- 'from' => '/some/path2?abcdef=&rv=',
85
- 'to' => 'www.google.com'
86
- }
87
- expect(TCellAgent.event_queue).to include(expected_as)
88
- end
89
-
90
- it 'sends redirect event with extra info' do
91
- response = request2.get(
92
- '/some/path2?abcdef=adsfsadf&rv=https://www.google.com',
93
- 'CONTENT_TYPE' => 'text/html',
94
- 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6'
95
- )
96
- expect(response['Location']).to eq('https://www.google.com')
97
- expected_as = {
98
- 'event_type' => 'redirect',
99
- 'method' => 'GET',
100
- 'from_domain' => 'example.org',
101
- 'status_code' => 200,
102
- 'remote_addr' => '1.3.3.4',
103
- 'rid' => 'myrouteid',
104
- 'from' => '/some/path2?abcdef=&rv=',
105
- 'to' => 'www.google.com',
106
- 'sid' => 'hmac_sessionid'
107
- }
108
- expect(TCellAgent.event_queue).to include(expected_as)
109
- end
110
- end
111
- end
112
- end
113
- end
114
- end
115
- end
116
- end
@@ -1,120 +0,0 @@
1
-
2
- require 'spec_helper'
3
-
4
- module TCellAgent
5
- module Rust
6
- describe '.create_request_response' do
7
- it 'should create request response' do
8
- meta_data = TCellAgent::MetaData.new(
9
- 'GET',
10
- '192.168.1.1',
11
- '12345',
12
- 'session_id',
13
- 'user_id',
14
- 'transaction_id',
15
- 'http://192.168.1.1/some/path?xss_param=<script>'
16
- )
17
- meta_data.response_code = 200
18
- meta_data.user_agent = 'Mozilla'
19
- meta_data.path = '/some/path'
20
- meta_data.request_content_bytes_len = 1024
21
- meta_data.response_content_bytes_len = 2048
22
- meta_data.get_dict = { 'user' => { 'xss_param' => '<script>' } }
23
- meta_data.sql_exceptions = [{ 'exception_name' => 'OperationalError', 'exception_payload' => 'Developer Error' }]
24
- meta_data.csrf_exception_name = 'ActionController::InvalidAuthenticityToken'
25
- meta_data.path_parameters = { 'xss_param' => '<script>' }
26
- meta_data.post_dict = { 'xss_param' => '<script>' }
27
- meta_data.cookie_dict = { 'xss_param' => '<script>' }
28
- meta_data.headers_dict = { 'HTTP_XSS_PARAM' => '<script>' }
29
- meta_data.content_type = 'hi'
30
- meta_data.raw_request_body = { 'xss_param' => '<script>' }.to_json
31
-
32
- result = Models.create_request_response(meta_data)
33
-
34
- expect(result).to eq(
35
- {
36
- 'method' => 'GET',
37
- 'status_code' => 200,
38
- 'route_id' => '12345',
39
- 'path' => '/some/path',
40
- 'query_params' => [
41
- { 'name' => 'xss_param', 'value' => '<script>' }
42
- ],
43
- 'post_params' => [
44
- { 'name' => 'xss_param', 'value' => '<script>' }
45
- ],
46
- 'headers' => [
47
- { 'name' => 'xss-param', 'value' => '<script>' }
48
- ],
49
- 'cookies' => [
50
- { 'name' => 'xss_param', 'value' => '<script>' }
51
- ],
52
- 'path_params' => [
53
- { 'name' => 'xss_param', 'value' => '<script>' }
54
- ],
55
- 'remote_address' => '192.168.1.1',
56
- 'full_uri' => 'http://192.168.1.1/some/path?xss_param=<script>',
57
- 'session_id' => 'session_id',
58
- 'user_id' => 'user_id',
59
- 'user_agent' => 'Mozilla',
60
- :content_type => 'hi',
61
- :request_body => '{"xss_param":"<script>"}',
62
- 'request_bytes_length' => 1024,
63
- 'response_bytes_length' => 2048,
64
- 'csrf_exception' => {
65
- 'exception_name' => 'ActionController::InvalidAuthenticityToken'
66
- },
67
- 'sql_exceptions' => [
68
- {
69
- 'exception_name' => 'OperationalError',
70
- 'exception_payload' => 'Developer Error'
71
- }
72
- ]
73
- }
74
- )
75
- end
76
- end
77
-
78
- describe '.create_patches_request' do
79
- it 'should create patches request' do
80
- meta_data = TCellAgent::MetaData.new(
81
- 'GET',
82
- '192.168.1.1',
83
- '12345',
84
- 'session_id',
85
- 'user_id',
86
- 'transaction_id',
87
- 'http://192.168.1.1/some/path?xss_param=<script>'
88
- )
89
-
90
- meta_data.path = '/some/path'
91
- meta_data.request_content_bytes_len = 1024
92
- meta_data.get_dict = { 'user' => { 'xss_param' => '<script>' } }
93
- meta_data.post_dict = { 'user' => { 'xss_param' => '<script>' } }
94
- meta_data.cookie_dict = { 'xss_param' => '<script>' }
95
- meta_data.headers_dict = { 'HTTP_XSS_PARAM' => '<script>' }
96
- meta_data.content_type = 'hi'
97
- # patches does not use the request body.
98
- meta_data.raw_request_body = { 'user' => { 'xss_param' => '<script>' } }.to_json
99
-
100
- result = Models.create_patches_request(meta_data)
101
-
102
- expect(result).to eq(
103
- {
104
- 'method' => 'GET',
105
- 'path' => '/some/path',
106
- 'remote_address' => '192.168.1.1',
107
- 'request_bytes_length' => 1024,
108
- :content_type => 'hi',
109
- 'query_params' => [{ 'name' => 'xss_param', 'value' => '<script>' }],
110
- 'post_params' => [
111
- { 'name' => 'xss_param', 'value' => '<script>' }
112
- ],
113
- 'headers' => [{ 'name' => 'xss-param', 'value' => '<script>' }],
114
- 'cookies' => [{ 'name' => 'xss_param', 'value' => '<script>' }]
115
- }
116
- )
117
- end
118
- end
119
- end
120
- end
@@ -1,704 +0,0 @@
1
-
2
- require 'spec_helper'
3
-
4
- module TCellAgent
5
- module Rust
6
- describe '.apply_cmdi' do
7
- require 'tcell_agent/rust/whisperer'
8
-
9
- before(:each) do
10
- configuration = double(
11
- 'configuration',
12
- {
13
- 'app_id' => 'app_id',
14
- 'api_key' => 'api_key',
15
- 'allow_payloads' => true,
16
- 'js_agent_api_base_url' => 'http://api.tcell.com/',
17
- 'js_agent_url' => 'https://jsagent.tcell.io/tcellagent.min.js',
18
- 'max_csp_header_bytes' => nil
19
- }
20
- )
21
- expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
22
- whisper = Whisperer.create_agent
23
- @agent_ptr = whisper['agent_ptr']
24
- @report_command_rule_id = 'TJM4ODvkB2jSR47qltL+0Nyy/PGlF6Qa/cin65qtIlc='
25
- @compound_rule_id = 'Y+IHN7BJDctqOIIZOb71NR8PkUxru01LDkqU1lZwogY='
26
- @block_whoois_on_path_rule_id = 'report-rule-with-path'
27
- policy = {
28
- 'cmdi' => {
29
- 'data' => {
30
- 'collect_full_commandline' => false,
31
- 'command_rules' => [
32
- {
33
- 'action' => 'report',
34
- 'rule_id' => @report_command_rule_id
35
- },
36
- {
37
- 'action' => 'block',
38
- 'rule_id' => @block_whoois_on_path_rule_id,
39
- 'command' => 'whoois',
40
- 'path' => { 'exact' => '/some/path', 'method' => 'GET' }
41
- }
42
- ],
43
- 'compound_statement_rules' => [
44
- {
45
- 'action' => 'report',
46
- 'rule_id' => @compound_rule_id
47
- }
48
- ]
49
- },
50
- 'policy_id' => '0cf0f090-ffc0-11e7-8080-808080808080',
51
- 'version' => 1
52
- }
53
- }
54
-
55
- whisper = Whisperer.update_policies(@agent_ptr, policy)
56
- expect(whisper['enablements']).to eq(
57
- {
58
- 'appfirewall' => false,
59
- 'patches' => false,
60
- 'cmdi' => true,
61
- 'headers' => false,
62
- 'jsagentinjection' => false
63
- }
64
- )
65
- @tcell_context = nil
66
- end
67
-
68
- after(:each) do
69
- Whisperer.free_agent(@agent_ptr)
70
- end
71
-
72
- context 'empty command' do
73
- it 'should return empty json object' do
74
- result = Whisperer.apply_cmdi(@agent_ptr, nil, @tcell_context)
75
- expect(result).to eq({})
76
- result = Whisperer.apply_cmdi(@agent_ptr, '', @tcell_context)
77
- expect(result).to eq({})
78
- result = Whisperer.apply_cmdi(@agent_ptr, ' ', @tcell_context)
79
- expect(result).to eq({})
80
- end
81
- end
82
-
83
- context 'with a path with method' do
84
- it 'that matches, should return event' do
85
- tcell_context = TCellAgent::Instrumentation::TCellData.new
86
- tcell_context.request_method = 'GET'
87
- tcell_context.path = '/some/path'
88
- result = Whisperer.apply_cmdi(@agent_ptr, 'whoois', tcell_context)
89
- expect(result).to eq(
90
- {
91
- 'apply_response' => {
92
- 'blocked' => true,
93
- 'commands' => [{ 'command' => 'whoois', 'arg_count' => 0 }],
94
- 'matches' => [{ 'rule_id' => @block_whoois_on_path_rule_id,
95
- 'command' => 'whoois' }],
96
- 'full_commandline' => nil
97
- }
98
- }
99
- )
100
- end
101
-
102
- it 'that does not match, should match generic report event' do
103
- # method doesn't match
104
- tcell_context = TCellAgent::Instrumentation::TCellData.new
105
- tcell_context.request_method = 'POST'
106
- tcell_context.path = '/some/path'
107
- result = Whisperer.apply_cmdi(@agent_ptr, 'whoois', tcell_context)
108
- expect(result).to eq(
109
- {
110
- 'apply_response' => {
111
- 'blocked' => false,
112
- 'commands' => [{ 'command' => 'whoois', 'arg_count' => 0 }],
113
- 'matches' => [{ 'rule_id' => @report_command_rule_id,
114
- 'command' => 'whoois' }],
115
- 'full_commandline' => nil
116
- }
117
- }
118
- )
119
-
120
- # path doesn't match
121
- tcell_context = TCellAgent::Instrumentation::TCellData.new
122
- tcell_context.request_method = 'GET'
123
- tcell_context.path = '/does/not/match'
124
- result = Whisperer.apply_cmdi(@agent_ptr, 'whoois', tcell_context)
125
- expect(result).to eq(
126
- {
127
- 'apply_response' => {
128
- 'blocked' => false,
129
- 'commands' => [{ 'command' => 'whoois', 'arg_count' => 0 }],
130
- 'matches' => [{ 'rule_id' => @report_command_rule_id,
131
- 'command' => 'whoois' }],
132
- 'full_commandline' => nil
133
- }
134
- }
135
- )
136
- end
137
- end
138
-
139
- context 'single command' do
140
- it 'should return single command parsed' do
141
- result = Whisperer.apply_cmdi(@agent_ptr, 'ifconfig -a', @tcell_context)
142
- expect(result).to eq({
143
- 'apply_response' => {
144
- 'blocked' => false,
145
- 'commands' => [{ 'command' => 'ifconfig', 'arg_count' => 1 }],
146
- 'matches' => [{ 'rule_id' => @report_command_rule_id,
147
- 'command' => 'ifconfig' }],
148
- 'full_commandline' => nil
149
- }
150
- })
151
- result = Whisperer.apply_cmdi(@agent_ptr, 'ifconfig', @tcell_context)
152
- expect(result).to eq({
153
- 'apply_response' => {
154
- 'blocked' => false,
155
- 'commands' => [{ 'command' => 'ifconfig', 'arg_count' => 0 }],
156
- 'matches' => [{ 'rule_id' => @report_command_rule_id,
157
- 'command' => 'ifconfig' }],
158
- 'full_commandline' => nil
159
- }
160
- })
161
- end
162
- end
163
-
164
- context 'with a compound command' do
165
- it 'should return parsed commands' do
166
- commands = Whisperer.apply_cmdi(
167
- @agent_ptr,
168
- 'cd /tcellagent_src && bundle --quiet && bundle exec rake compile && bundle exec rspec',
169
- @tcell_context
170
- )
171
- expect(commands).to eq({
172
- 'apply_response' => {
173
- 'blocked' => false,
174
- 'commands' => [
175
- { 'command' => 'cd', 'arg_count' => 1 },
176
- { 'command' => 'bundle', 'arg_count' => 1 },
177
- { 'command' => 'bundle', 'arg_count' => 3 },
178
- { 'command' => 'bundle', 'arg_count' => 2 }
179
- ],
180
- 'matches' => [{ 'rule_id' => @compound_rule_id, 'command' => nil },
181
- { 'rule_id' => @report_command_rule_id, 'command' => 'cd' },
182
- { 'rule_id' => @report_command_rule_id, 'command' => 'bundle' },
183
- { 'rule_id' => @report_command_rule_id, 'command' => 'bundle' },
184
- { 'rule_id' => @report_command_rule_id, 'command' => 'bundle' }],
185
- 'full_commandline' => nil
186
- }
187
- })
188
-
189
- commands = Whisperer.apply_cmdi(
190
- @agent_ptr,
191
- 'cd /tcellagent_src; bundle --quiet; bundle exec rake compile; bundle exec rspec',
192
- @tcell_context
193
- )
194
- expect(commands).to eq({
195
- 'apply_response' => {
196
- 'blocked' => false,
197
- 'commands' => [
198
- { 'command' => 'cd', 'arg_count' => 1 },
199
- { 'command' => 'bundle', 'arg_count' => 1 },
200
- { 'command' => 'bundle', 'arg_count' => 3 },
201
- { 'command' => 'bundle', 'arg_count' => 2 }
202
- ],
203
- 'matches' => [
204
- { 'rule_id' => @compound_rule_id, 'command' => nil },
205
- { 'rule_id' => @report_command_rule_id, 'command' => 'cd' },
206
- { 'rule_id' => @report_command_rule_id, 'command' => 'bundle' },
207
- { 'rule_id' => @report_command_rule_id, 'command' => 'bundle' },
208
- { 'rule_id' => @report_command_rule_id, 'command' => 'bundle' }
209
- ],
210
- 'full_commandline' => nil
211
- }
212
- })
213
-
214
- commands = Whisperer.apply_cmdi(
215
- @agent_ptr,
216
- 'cat /etc/passwd | grep root',
217
- @tcell_context
218
- )
219
- expect(commands).to eq({
220
- 'apply_response' => {
221
- 'blocked' => false,
222
- 'commands' => [
223
- { 'command' => 'cat', 'arg_count' => 1 },
224
- { 'command' => 'grep', 'arg_count' => 1 }
225
- ],
226
- 'matches' => [
227
- { 'rule_id' => @compound_rule_id, 'command' => nil },
228
- { 'rule_id' => @report_command_rule_id, 'command' => 'cat' },
229
- { 'rule_id' => @report_command_rule_id, 'command' => 'grep' }
230
- ],
231
- 'full_commandline' => nil
232
- }
233
- })
234
- end
235
-
236
- context 'spawning multiple lines' do
237
- it 'should parse the commands' do
238
- multiline_command = "echo 'first-line'; \ \n" \
239
- 'cat /etc/passwd | grep root'
240
- commands = Whisperer.apply_cmdi(
241
- @agent_ptr,
242
- multiline_command,
243
- @tcell_context
244
- )
245
-
246
- expect(commands).to eq({
247
- 'apply_response' => {
248
- 'blocked' => false,
249
- 'commands' => [
250
- { 'command' => 'echo', 'arg_count' => 1 },
251
- { 'command' => 'cat', 'arg_count' => 1 },
252
- { 'command' => 'grep', 'arg_count' => 1 }
253
- ],
254
- 'matches' => [
255
- { 'rule_id' => @compound_rule_id, 'command' => nil },
256
- { 'rule_id' => @report_command_rule_id, 'command' => 'echo' },
257
- { 'rule_id' => @report_command_rule_id, 'command' => 'cat' },
258
- { 'rule_id' => @report_command_rule_id, 'command' => 'grep' }
259
- ],
260
- 'full_commandline' => nil
261
- }
262
- })
263
-
264
- multiline_command = "echo 'first-line' && \ \n" \
265
- 'cat /etc/passwd | grep root'
266
- commands = Whisperer.apply_cmdi(
267
- @agent_ptr,
268
- multiline_command,
269
- @tcell_context
270
- )
271
- expect(commands).to eq({
272
- 'apply_response' => {
273
- 'blocked' => false,
274
- 'commands' => [
275
- { 'command' => 'echo', 'arg_count' => 1 },
276
- { 'command' => 'cat', 'arg_count' => 1 },
277
- { 'command' => 'grep', 'arg_count' => 1 }
278
- ],
279
- 'matches' => [
280
- { 'rule_id' => @compound_rule_id, 'command' => nil },
281
- { 'rule_id' => @report_command_rule_id, 'command' => 'echo' },
282
- { 'rule_id' => @report_command_rule_id, 'command' => 'cat' },
283
- { 'rule_id' => @report_command_rule_id, 'command' => 'grep' }
284
- ],
285
- 'full_commandline' => nil
286
- }
287
- })
288
-
289
- multiline_command = "cd /tcellagent_src; bundle --quiet; \ \n" \
290
- "bundle exec rake compile; \ \n" \
291
- 'bundle exec rspec'
292
- commands = Whisperer.apply_cmdi(
293
- @agent_ptr,
294
- multiline_command,
295
- @tcell_context
296
- )
297
- expect(commands).to eq({
298
- 'apply_response' => {
299
- 'blocked' => false,
300
- 'commands' => [
301
- { 'command' => 'cd', 'arg_count' => 1 },
302
- { 'command' => 'bundle', 'arg_count' => 1 },
303
- { 'command' => 'bundle', 'arg_count' => 3 },
304
- { 'command' => 'bundle', 'arg_count' => 2 }
305
- ],
306
- 'matches' => [
307
- { 'rule_id' => @compound_rule_id, 'command' => nil },
308
- { 'rule_id' => @report_command_rule_id, 'command' => 'cd' },
309
- { 'rule_id' => @report_command_rule_id, 'command' => 'bundle' },
310
- { 'rule_id' => @report_command_rule_id, 'command' => 'bundle' },
311
- { 'rule_id' => @report_command_rule_id, 'command' => 'bundle' }
312
- ],
313
- 'full_commandline' => nil
314
- }
315
- })
316
- end
317
- end
318
- end
319
-
320
- context 'with a complex command' do
321
- it 'should parse the commands' do
322
- multiline_command = "magick -size 320x85 canvas:none -font Bookman-DemiItalic -pointsize 72 \\ \n" \
323
- "-draw \"text 25,60 \'Magick\'\" -channel RGBA -blur 0x6 -fill darkred -stroke magenta \\ \n" \
324
- "-draw \"text 20,55 \'Magick\'\" fuzzy-magick.png"
325
- commands = Whisperer.apply_cmdi(
326
- @agent_ptr,
327
- multiline_command,
328
- @tcell_context
329
- )
330
- expect(commands).to eq({
331
- 'apply_response' => {
332
- 'blocked' => false,
333
- 'commands' => [{ 'command' => 'magick', 'arg_count' => 26 }],
334
- 'matches' => [{ 'rule_id' => @report_command_rule_id, 'command' => 'magick' }],
335
- 'full_commandline' => nil
336
- }
337
- })
338
-
339
- commands = Whisperer.apply_cmdi(
340
- @agent_ptr,
341
- "/usr/local/bin/ruby -eputs 'Hello World!' > /dev/null 2>&1",
342
- @tcell_context
343
- )
344
- expect(commands).to eq({
345
- 'apply_response' => {
346
- 'blocked' => false,
347
- 'commands' => [{ 'command' => 'ruby', 'arg_count' => 6 }],
348
- 'matches' => [{ 'rule_id' => @report_command_rule_id, 'command' => 'ruby' }],
349
- 'full_commandline' => nil
350
- }
351
- })
352
- end
353
- end
354
-
355
- context 'with special characters in the command' do
356
- it 'should parse the commands' do
357
- commands = Whisperer.apply_cmdi(
358
- @agent_ptr,
359
- "echo 'bréak' && cat /etc/passwd && grep root",
360
- @tcell_context
361
- )
362
- expect(commands).to eq({
363
- 'apply_response' => {
364
- 'blocked' => false,
365
- 'commands' => [
366
- { 'command' => 'echo', 'arg_count' => 1 },
367
- { 'command' => 'cat', 'arg_count' => 1 },
368
- { 'command' => 'grep', 'arg_count' => 1 }
369
- ],
370
- 'matches' => [
371
- { 'rule_id' => @compound_rule_id, 'command' => nil },
372
- { 'rule_id' => @report_command_rule_id, 'command' => 'echo' },
373
- { 'rule_id' => @report_command_rule_id, 'command' => 'cat' },
374
- { 'rule_id' => @report_command_rule_id, 'command' => 'grep' }
375
- ],
376
- 'full_commandline' => nil
377
- }
378
- })
379
- end
380
- end
381
-
382
- context 'with null terminator character in the command' do
383
- it 'should parse the commands' do
384
- commands = Whisperer.apply_cmdi(
385
- @agent_ptr,
386
- "echo 'br\0ak' && cat /etc/passwd && grep root",
387
- @tcell_context
388
- )
389
- expect(commands).to eq({
390
- 'apply_response' => {
391
- 'blocked' => false,
392
- 'commands' => [
393
- { 'command' => 'echo', 'arg_count' => 1 },
394
- { 'command' => 'cat', 'arg_count' => 1 },
395
- { 'command' => 'grep', 'arg_count' => 1 }
396
- ],
397
- 'matches' => [
398
- { 'rule_id' => @compound_rule_id, 'command' => nil },
399
- { 'rule_id' => @report_command_rule_id, 'command' => 'echo' },
400
- { 'rule_id' => @report_command_rule_id, 'command' => 'cat' },
401
- { 'rule_id' => @report_command_rule_id, 'command' => 'grep' }
402
- ],
403
- 'full_commandline' => nil
404
- }
405
- })
406
- end
407
- end
408
-
409
- context 'with an sh command' do
410
- it 'should parse the commands' do
411
- commands = Whisperer.apply_cmdi(
412
- @agent_ptr,
413
- 'sh -c "bundle install && rake db:setup db:migrate"',
414
- @tcell_context
415
- )
416
- expect(commands).to eq(
417
- {
418
- 'apply_response' => {
419
- 'blocked' => false,
420
- 'commands' => [
421
- { 'command' => 'sh', 'arg_count' => 2 },
422
- { 'command' => 'bundle', 'arg_count' => 1 },
423
- { 'command' => 'rake', 'arg_count' => 2 }
424
- ],
425
- 'matches' => [
426
- { 'rule_id' => @compound_rule_id, 'command' => nil },
427
- { 'rule_id' => @report_command_rule_id, 'command' => 'sh' },
428
- { 'rule_id' => @report_command_rule_id, 'command' => 'bundle' },
429
- { 'rule_id' => @report_command_rule_id, 'command' => 'rake' }
430
- ],
431
- 'full_commandline' => nil
432
- }
433
- }
434
- )
435
- end
436
- end
437
-
438
- context 'with an /bin/sh command' do
439
- it 'should parse the commands' do
440
- commands = Whisperer.apply_cmdi(
441
- @agent_ptr,
442
- '/bin/sh -c "bundle install && rake db:setup db:migrate"',
443
- @tcell_context
444
- )
445
- expect(commands).to eq(
446
- {
447
- 'apply_response' => {
448
- 'blocked' => false,
449
- 'commands' => [
450
- { 'command' => 'sh', 'arg_count' => 2 },
451
- { 'command' => 'bundle', 'arg_count' => 1 },
452
- { 'command' => 'rake', 'arg_count' => 2 }
453
- ],
454
- 'matches' => [
455
- { 'rule_id' => @compound_rule_id, 'command' => nil },
456
- { 'rule_id' => @report_command_rule_id, 'command' => 'sh' },
457
- { 'rule_id' => @report_command_rule_id, 'command' => 'bundle' },
458
- { 'rule_id' => @report_command_rule_id, 'command' => 'rake' }
459
- ],
460
- 'full_commandline' => nil
461
- }
462
- }
463
- )
464
- end
465
- end
466
- end
467
-
468
- describe '.convert_result' do
469
- it 'should log bad responses from native library' do
470
- logger = double('logger')
471
- expect(TCellAgent).to receive(:logger).and_return(logger)
472
- expect(logger).to receive(:error).with(
473
- 'Error response from `create_agent` in native library: -1'
474
- )
475
-
476
- result = FFI::MemoryPointer.from_string('')
477
- expect(Whisperer.convert_result('create_agent', -1, result)).to eq({})
478
- end
479
-
480
- it 'should catch and log json parse errors' do
481
- logger = double('logger')
482
- expect(TCellAgent).to receive(:logger).and_return(logger)
483
- expect(logger).to receive(:error).with(
484
- 'Could not parse json response from `create_agent` in native library.'
485
- )
486
-
487
- result = FFI::MemoryPointer.from_string('{malformed_json}')
488
- whisper = Whisperer.convert_result('create_agent', result.size, result)
489
- expect(whisper).to eq({})
490
- end
491
-
492
- it 'should parse json properly' do
493
- result = FFI::MemoryPointer.from_string({ 'valid' => 'json' }.to_json)
494
- whisper = Whisperer.convert_result('create_agent', result.size, result)
495
- expect(whisper).to eq({ 'valid' => 'json' })
496
- end
497
- end
498
-
499
- describe '.apply_appfirewall and .apply_patches' do
500
- before(:each) do
501
- configuration = double(
502
- 'configuration',
503
- {
504
- 'app_id' => 'app_id',
505
- 'api_key' => 'api_key',
506
- 'allow_payloads' => true,
507
- 'js_agent_api_base_url' => 'http://api.tcell.com/',
508
- 'js_agent_url' => 'https://jsagent.tcell.io/tcellagent.min.js',
509
- 'max_csp_header_bytes' => nil
510
- }
511
- )
512
- expect(TCellAgent).to receive(:configuration).and_return(configuration).at_least(:once)
513
- whisper = Whisperer.create_agent
514
- @agent_ptr = whisper['agent_ptr']
515
- policy = {
516
- 'regex' => {
517
- 'data' => {
518
- 'patterns' => [
519
- {
520
- 'id' => 'tc-xss-1',
521
- 'pattern' => '(?:<(script|iframe|embed|frame|frameset|object|img|applet|body|html|style|layer|link|ilayer|meta|bgsound))',
522
- 'sensor' => 'xss',
523
- 'title' => 'Basic Injection'
524
- }
525
- ],
526
- 'version' => 1_518_546_622_571
527
- },
528
- 'policy_id' => 'regex-policy-id',
529
- 'version' => 1
530
- },
531
-
532
- 'appsensor' => {
533
- 'policy_id' => 'appsensor-policy-id',
534
- 'version' => 2,
535
- 'data' => {
536
- 'sensors' => {
537
- 'ignore_rules' => [],
538
- 'errors' => {
539
- 'csrf_exception_enabled' => true,
540
- 'sql_exception_enabled' => true
541
- },
542
- 'xss' => {
543
- 'dynamic_patterns' => ['tc-xss-1'],
544
- 'patterns' => ['1']
545
- }
546
- }
547
- }
548
- },
549
-
550
- 'patches' => {
551
- 'data' => {
552
- 'block_rules' => [],
553
- 'blocked_ips' => [],
554
- 'payloads' => {
555
- 'send_payloads' => true
556
- },
557
- 'rules' => [
558
- {
559
- 'action' => 'BlockIf',
560
- 'destinations' => { 'check_equals' => [{ 'path' => '*' }] },
561
- 'id' => 'check-present-rule',
562
- 'ignore' => [],
563
- 'matches' => [
564
- {
565
- 'all' => [
566
- {
567
- 'parameters' => {
568
- 'check_present' => {
569
- 'queries' => [
570
- 'xss_param'
571
- ]
572
- }
573
- }
574
- }
575
- ],
576
- 'any' => []
577
- }
578
- ],
579
- 'title' => 'check present rule'
580
- }
581
- ]
582
- },
583
- 'policy_id' => 'patches-v1-14',
584
- 'version' => 2
585
- }
586
- }
587
-
588
- whisper = Whisperer.update_policies(@agent_ptr, policy)
589
- expect(whisper['enablements']).to eq(
590
- {
591
- 'appfirewall' => true,
592
- 'patches' => true,
593
- 'cmdi' => false,
594
- 'headers' => false,
595
- 'jsagentinjection' => false
596
- }
597
- )
598
- end
599
-
600
- after(:each) do
601
- Whisperer.free_agent(@agent_ptr)
602
- end
603
-
604
- it 'should return appfirewall injections' do
605
- meta_data = TCellAgent::MetaData.new(
606
- 'GET',
607
- '192.168.1.1',
608
- '12345',
609
- 'session_id',
610
- 'user_id',
611
- 'transaction_id',
612
- 'http://192.168.1.1/some/path?xss_param=<script>'
613
- )
614
- meta_data.path = '/some/path'
615
- meta_data.request_content_bytes_len = 1024
616
- meta_data.response_content_bytes_len = 2048
617
- meta_data.get_dict = { 'xss_param' => '<script>' }
618
- meta_data.user_agent = 'Mozilla'
619
- meta_data.sql_exceptions = [
620
- {
621
- 'exception_name' => 'OperationalError',
622
- 'exception_payload' => 'Developer Error'
623
- }
624
- ]
625
- meta_data.csrf_exception_name = 'ActionController::InvalidAuthenticityToken'
626
-
627
- whisper = Whisperer.apply_appfirewall(
628
- @agent_ptr,
629
- meta_data
630
- )
631
- expect(whisper).to eq(
632
- {
633
- 'apply_response' => [
634
- {
635
- 'detection_point' => 'xss',
636
- 'method' => 'GET',
637
- 'parameter' => 'xss_param',
638
- 'uri' => 'http://192.168.1.1/some/path?xss_param=',
639
- 'remote_address' => '192.168.1.1',
640
- 'route_id' => '12345',
641
- 'session_id' => 'session_id',
642
- 'user_id' => 'user_id',
643
- 'pattern' => 'tc-xss-1',
644
- 'meta' => { 'l' => 'query', 'h' => [], 'num_headers' => 0, 'summary' => [] }
645
- },
646
- {
647
- 'detection_point' => 'exsql',
648
- 'method' => 'GET',
649
- 'parameter' => 'OperationalError',
650
- 'uri' => 'http://192.168.1.1/some/path?xss_param=',
651
- 'remote_address' => '192.168.1.1',
652
- 'route_id' => '12345',
653
- 'session_id' => 'session_id',
654
- 'user_id' => 'user_id'
655
- },
656
- {
657
- 'detection_point' => 'excsrf',
658
- 'method' => 'GET',
659
- 'parameter' => 'ActionController::InvalidAuthenticityToken',
660
- 'uri' => 'http://192.168.1.1/some/path?xss_param=',
661
- 'remote_address' => '192.168.1.1',
662
- 'route_id' => '12345',
663
- 'session_id' => 'session_id',
664
- 'user_id' => 'user_id'
665
- }
666
- ]
667
- }
668
- )
669
- end
670
-
671
- it 'should return patches blocking' do
672
- meta_data = TCellAgent::MetaData.new(
673
- 'GET',
674
- '192.168.1.1',
675
- '12345',
676
- 'session_id',
677
- 'user_id',
678
- 'transaction_id',
679
- 'http://192.168.1.1/some/path?xss_param=<script>'
680
- )
681
- meta_data.path = '/some/path'
682
- meta_data.request_content_bytes_len = 1024
683
- meta_data.get_dict = { 'xss_param' => '<script>' }
684
- whisper = Whisperer.apply_patches(
685
- @agent_ptr,
686
- meta_data
687
- )
688
- expect(whisper).to eq(
689
- {
690
- 'apply_response' => {
691
- 'status' => 'Blocked',
692
- 'patches_policy_id' => 'patches-v1-14',
693
- 'rule_id' => 'check-present-rule',
694
- 'regex_pid' => 'regex-policy-id',
695
- 'payload' => [
696
- { 'l' => 'query', 'name' => 'xss_param', 'val' => '<script>' }
697
- ]
698
- }
699
- }
700
- )
701
- end
702
- end
703
- end
704
- end