tcell_agent 2.0.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +2 -2
  3. data/bin/tcell_agent +41 -150
  4. data/lib/tcell_agent/agent.rb +87 -52
  5. data/lib/tcell_agent/config_initializer.rb +63 -0
  6. data/lib/tcell_agent/configuration.rb +72 -267
  7. data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
  8. data/lib/tcell_agent/instrument_servers.rb +14 -18
  9. data/lib/tcell_agent/instrumentation/cmdi.rb +47 -15
  10. data/lib/tcell_agent/instrumentation/lfi.rb +72 -15
  11. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/file.rb +21 -0
  12. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/io.rb +75 -0
  13. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/kernel.rb +80 -0
  14. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/file.rb +21 -0
  15. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/io.rb +75 -0
  16. data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/kernel.rb +80 -0
  17. data/lib/tcell_agent/instrumentation.rb +14 -6
  18. data/lib/tcell_agent/logger.rb +3 -4
  19. data/lib/tcell_agent/policies/command_injection_policy.rb +1 -1
  20. data/lib/tcell_agent/policies/dataloss_policy.rb +15 -8
  21. data/lib/tcell_agent/policies/headers_policy.rb +2 -2
  22. data/lib/tcell_agent/policies/patches_policy.rb +8 -4
  23. data/lib/tcell_agent/policies/policies_manager.rb +1 -0
  24. data/lib/tcell_agent/policies/policy_polling.rb +4 -3
  25. data/lib/tcell_agent/rails/auth/authlogic.rb +49 -44
  26. data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
  27. data/lib/tcell_agent/rails/auth/devise.rb +103 -102
  28. data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
  29. data/lib/tcell_agent/rails/auth/doorkeeper.rb +54 -57
  30. data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
  31. data/lib/tcell_agent/rails/better_ip.rb +7 -19
  32. data/lib/tcell_agent/rails/csrf_exception.rb +0 -8
  33. data/lib/tcell_agent/rails/dlp/process_request.rb +5 -0
  34. data/lib/tcell_agent/rails/dlp.rb +58 -56
  35. data/lib/tcell_agent/rails/dlp_handler.rb +9 -10
  36. data/lib/tcell_agent/rails/js_agent_insert.rb +2 -3
  37. data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -1
  38. data/lib/tcell_agent/rails/middleware/global_middleware.rb +3 -4
  39. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
  40. data/lib/tcell_agent/rails/{on_start.rb → railties/tcell_agent_railties.rb} +9 -16
  41. data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
  42. data/lib/tcell_agent/rails/routes/grape.rb +5 -12
  43. data/lib/tcell_agent/rails/routes.rb +6 -9
  44. data/lib/tcell_agent/rails/settings_reporter.rb +3 -6
  45. data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -7
  46. data/lib/tcell_agent/routes/table.rb +3 -0
  47. data/lib/tcell_agent/rust/agent_config.rb +62 -33
  48. data/lib/tcell_agent/rust/{libtcellagent-4.14.0.so → libtcellagent-alpine.so} +0 -0
  49. data/lib/tcell_agent/rust/{libtcellagent-4.14.0.dylib → libtcellagent-x64.dll} +0 -0
  50. data/lib/tcell_agent/rust/{libtcellagent-alpine-4.14.0.so → libtcellagent.dylib} +0 -0
  51. data/lib/tcell_agent/rust/libtcellagent.so +0 -0
  52. data/lib/tcell_agent/rust/models.rb +9 -0
  53. data/lib/tcell_agent/rust/native_agent.rb +61 -51
  54. data/lib/tcell_agent/rust/native_library.rb +8 -10
  55. data/lib/tcell_agent/sensor_events/server_agent.rb +3 -100
  56. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +1 -0
  57. data/lib/tcell_agent/servers/puma.rb +30 -13
  58. data/lib/tcell_agent/servers/rack_puma_handler.rb +33 -0
  59. data/lib/tcell_agent/servers/rails_server.rb +4 -4
  60. data/lib/tcell_agent/servers/unicorn.rb +1 -1
  61. data/lib/tcell_agent/servers/webrick.rb +12 -3
  62. data/lib/tcell_agent/settings_reporter.rb +0 -93
  63. data/lib/tcell_agent/sinatra.rb +1 -0
  64. data/lib/tcell_agent/tcell_context.rb +16 -7
  65. data/lib/tcell_agent/utils/headers.rb +0 -1
  66. data/lib/tcell_agent/utils/strings.rb +2 -2
  67. data/lib/tcell_agent/version.rb +1 -1
  68. data/lib/tcell_agent.rb +8 -16
  69. data/spec/cruby_spec_helper.rb +26 -0
  70. data/spec/lib/tcell_agent/configuration_spec.rb +62 -212
  71. data/spec/lib/tcell_agent/instrument_servers_spec.rb +95 -0
  72. data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
  73. data/spec/lib/tcell_agent/{cmdi_spec.rb → instrumentation/cmdi_spec.rb} +50 -0
  74. data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +211 -272
  75. data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +213 -223
  76. data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +95 -61
  77. data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +120 -2
  78. data/spec/lib/tcell_agent/patches_spec.rb +2 -1
  79. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +1 -2
  80. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +5 -6
  81. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +21 -2
  82. data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +1 -1
  83. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +13 -8
  84. data/spec/lib/tcell_agent/rails/better_ip_spec.rb +9 -11
  85. data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +6 -6
  86. data/spec/lib/tcell_agent/rails/dlp_spec.rb +1 -0
  87. data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +10 -2
  88. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -1
  89. data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +4 -4
  90. data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
  91. data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -89
  92. data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
  93. data/spec/spec_helper.rb +9 -1
  94. data/spec/support/builders.rb +8 -7
  95. data/spec/support/server_mocks/passenger_mock.rb +7 -0
  96. data/spec/support/server_mocks/puma_mock.rb +21 -0
  97. data/spec/support/server_mocks/rails_mock.rb +7 -0
  98. data/spec/support/server_mocks/thin_mock.rb +7 -0
  99. data/spec/support/server_mocks/unicorn_mock.rb +11 -0
  100. data/spec/support/shared_spec.rb +29 -0
  101. data/tcell_agent.gemspec +14 -14
  102. metadata +46 -29
  103. data/Rakefile +0 -18
  104. data/lib/tcell_agent/authlogic.rb +0 -23
  105. data/lib/tcell_agent/config/unknown_options.rb +0 -119
  106. data/lib/tcell_agent/devise.rb +0 -33
  107. data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +0 -25
  108. data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +0 -123
  109. data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +0 -159
  110. data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
  111. data/lib/tcell_agent/rust/tcellagent-4.14.0.dll +0 -0
  112. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
@@ -2,6 +2,7 @@
2
2
  # rubocop:disable Lint/UselessAssignment
3
3
  require 'spec_helper'
4
4
  require 'securerandom'
5
+ require 'pathname'
5
6
 
6
7
  describe 'Kernel' do
7
8
  before do
@@ -14,11 +15,12 @@ describe 'Kernel' do
14
15
  end
15
16
 
16
17
  before(:all) do
17
- @new_file_name = '/tmp/' + SecureRandom.uuid
18
+ @new_file_name = NEW_FILE_NAME
19
+ @new_pathname = Pathname.new(@new_file_name)
18
20
  end
19
21
  describe '#open and ::open' do
20
22
  context 'empty path' do
21
- it 'should raise an error' do
23
+ it 'raises an error' do
22
24
  expect do
23
25
  Kernel.open
24
26
  end.to raise_error(ArgumentError)
@@ -39,106 +41,138 @@ describe 'Kernel' do
39
41
  end.to raise_error(Errno::ENOENT)
40
42
  end
41
43
  end
42
- context 'with a filename not blocked for read/write' do
44
+ context 'with filename not blocked for read/write' do
43
45
  before do |test|
44
46
  unless test.metadata[:skip_before]
45
47
  expect(TCellAgent).to receive(:policy).with(
46
48
  TCellAgent::PolicyTypes::LFI
47
49
  ).and_return(@local_files_policy, @local_files_policy)
48
50
  expect(@local_files_policy).to receive(:block_file_access?).and_return(false, false)
51
+ expect(TCellAgent::Cmdi).not_to receive(:parse_command_from_open)
49
52
  end
50
53
  end
51
54
 
52
- it 'should still be able to execute OS commands', :skip_before do
55
+ it 'executes OS commands', :skip_before do
53
56
  result = Kernel.open('|echo test').read
54
57
  expect(result).to eq "test\n"
55
58
 
56
59
  result = open('|echo test').read
57
60
  expect(result).to eq "test\n"
58
61
  end
59
- context 'with a nonexistent filename with mode w' do
60
- it 'should create the file' do
61
- Kernel.open(@new_file_name, 'w')
62
- expect(File.exist?(@new_file_name)).to be_truthy
63
- File.delete(@new_file_name)
64
62
 
65
- open(@new_file_name, 'w')
66
- expect(File.exist?(@new_file_name)).to be_truthy
67
- File.delete(@new_file_name)
68
- end
63
+ it 'creates the file when passed a pathname' do
64
+ Kernel.open(@new_pathname, 'w')
65
+ expect(File.exist?(@new_pathname)).to be_truthy
66
+ File.delete(@new_pathname)
67
+
68
+ open(@new_pathname, 'w')
69
+ expect(File.exist?(@new_pathname)).to be_truthy
70
+ File.delete(@new_pathname)
69
71
  end
70
- context 'with a filename and mode w and file permissions 644' do
71
- it 'should create the file with the correct permissions' do
72
- Kernel.open(@new_file_name, 'w', 0o644)
73
- expect(File.stat(@new_file_name).mode.to_s(8)[3..5]).to eq('644')
74
- File.delete(@new_file_name)
75
72
 
76
- open(@new_file_name, 'w', 0o644)
77
- expect(File.stat(@new_file_name).mode.to_s(8)[3..5]).to eq('644')
78
- File.delete(@new_file_name)
79
- end
73
+ it 'creates the file when passed a string' do
74
+ Kernel.open(@new_file_name, 'w')
75
+ expect(File.exist?(@new_file_name)).to be_truthy
76
+ File.delete(@new_file_name)
77
+
78
+ open(@new_file_name, 'w')
79
+ expect(File.exist?(@new_file_name)).to be_truthy
80
+ File.delete(@new_file_name)
81
+ end
82
+
83
+ it 'creates the file with the permission 644' do
84
+ Kernel.open(@new_file_name, 'w', 0o644)
85
+ expect(File.stat(@new_file_name).mode.to_s(8)[3..5]).to eq('644')
86
+ File.delete(@new_file_name)
87
+
88
+ open(@new_file_name, 'w', 0o644)
89
+ expect(File.stat(@new_file_name).mode.to_s(8)[3..5]).to eq('644')
90
+ File.delete(@new_file_name)
80
91
  end
81
- context 'with a filename and mode w and file permissions 777' do
82
- it 'should create the file with the correct permissions 755' do
83
- Kernel.open(@new_file_name, 'w', 0o777)
84
- expect(File.stat(@new_file_name).mode.to_s(8)[3..5]).to eq('755')
85
- File.delete(@new_file_name)
86
92
 
87
- open(@new_file_name, 'w', 0o777)
93
+ it 'creates the file with the permission 755' do
94
+ Kernel.open(@new_file_name, 'w', 0o777)
95
+ expect(File.stat(@new_file_name).mode.to_s(8)[3..5]).to eq('755')
96
+ File.delete(@new_file_name)
97
+
98
+ open(@new_file_name, 'w', 0o777)
99
+ expect(File.stat(@new_file_name).mode.to_s(8)[3..5]).to eq('755')
100
+ File.delete(@new_file_name)
101
+ end
102
+
103
+ context 'using mode, perm, binmode', :skip_before do
104
+ before(:each) do
105
+ expect(TCellAgent).to receive(:policy).with(
106
+ TCellAgent::PolicyTypes::LFI
107
+ ).and_return(@local_files_policy)
108
+ expect(@local_files_policy).to receive(:block_file_access?).and_return(false)
109
+ expect(TCellAgent::Cmdi).not_to receive(:parse_command_from_open)
110
+ end
111
+
112
+ after :each do
88
113
  expect(File.stat(@new_file_name).mode.to_s(8)[3..5]).to eq('755')
89
- File.delete(@new_file_name)
114
+ expect(@result.binmode?).to eq true
115
+
116
+ File.delete(NEW_FILE_NAME) if File.exist?(NEW_FILE_NAME)
90
117
  end
118
+
119
+ test_ruby2_ruby3_keywords(Kernel,
120
+ 'open',
121
+ [NEW_FILE_NAME, 'w', 0o755],
122
+ { :binmode => true },
123
+ nil)
124
+
125
+ test_ruby2_ruby3_keywords(Object,
126
+ 'open',
127
+ [NEW_FILE_NAME, 'w', 0o755],
128
+ { :binmode => true },
129
+ nil)
91
130
  end
92
131
  end
93
- context 'with a filename blocked for read/write' do
132
+ context 'with filename blocked for read/write' do
94
133
  before do |test|
95
134
  unless test.metadata[:skip_before]
96
135
  expect(TCellAgent).to receive(:policy).with(
97
136
  TCellAgent::PolicyTypes::LFI
98
137
  ).and_return(@local_files_policy, @local_files_policy)
99
138
  expect(@local_files_policy).to receive(:block_file_access?).and_return(true, true)
139
+ expect(TCellAgent::Cmdi).not_to receive(:parse_command_from_open)
100
140
  end
101
141
  end
102
142
 
103
- it 'should still be able to execute OS commands', :skip_before do
143
+ it 'executes OS commands', :skip_before do
104
144
  result = Kernel.open('|echo test').read
105
145
  expect(result).to eq "test\n"
106
146
 
107
147
  result = open('|echo test').read
108
148
  expect(result).to eq "test\n"
109
149
  end
110
- context 'with a nonexistent filename with mode w' do
111
- it 'should raise an error' do
112
- expect do
113
- Kernel.open(@new_file_name, 'w')
114
- end.to raise_error(IOError)
150
+ it 'raises an IOError' do
151
+ expect do
152
+ Kernel.open(@new_file_name, 'w')
153
+ end.to raise_error(IOError)
115
154
 
116
- expect do
117
- open(@new_file_name, 'w')
118
- end.to raise_error(IOError)
119
- end
155
+ expect do
156
+ open(@new_file_name, 'w')
157
+ end.to raise_error(IOError)
120
158
  end
121
- context 'with a filename and mode w' do
122
- it 'should raise an error' do
123
- expect do
124
- Kernel.open(@new_file_name, 'w')
125
- end.to raise_error(IOError)
159
+ it 'raises an IOError' do
160
+ expect do
161
+ Kernel.open(@new_file_name, 'w')
162
+ end.to raise_error(IOError)
126
163
 
127
- expect do
128
- open(@new_file_name, 'w')
129
- end.to raise_error(IOError)
130
- end
164
+ expect do
165
+ open(@new_file_name, 'w')
166
+ end.to raise_error(IOError)
131
167
  end
132
- context 'with a filename and mode a' do
133
- it 'should raise an error' do
134
- expect do
135
- Kernel.open(@new_file_name, 'a')
136
- end.to raise_error(IOError)
168
+ it 'raises an IOError' do
169
+ expect do
170
+ Kernel.open(@new_file_name, 'a')
171
+ end.to raise_error(IOError)
137
172
 
138
- expect do
139
- open(@new_file_name, 'a')
140
- end.to raise_error(IOError)
141
- end
173
+ expect do
174
+ open(@new_file_name, 'a')
175
+ end.to raise_error(IOError)
142
176
  end
143
177
  end
144
178
  end
@@ -169,7 +203,7 @@ describe 'Kernel' do
169
203
  end
170
204
  end
171
205
  context 'with a filename blocked for read/write' do
172
- it 'should not be able to read the file' do
206
+ it 'raises an IOError' do
173
207
  expect(TCellAgent).to receive(:policy).with(
174
208
  TCellAgent::PolicyTypes::LFI
175
209
  ).and_return(@local_files_policy, @local_files_policy)
@@ -196,7 +230,7 @@ describe 'Kernel' do
196
230
 
197
231
  describe '::readline and #readline' do
198
232
  context 'with a filename not blocked for read/write' do
199
- it 'should be able to read the file' do
233
+ it 'reads the file' do
200
234
  expect(TCellAgent).to receive(:policy).with(
201
235
  TCellAgent::PolicyTypes::LFI
202
236
  ).and_return(@local_files_policy, @local_files_policy, @local_files_policy, @local_files_policy)
@@ -221,7 +255,7 @@ describe 'Kernel' do
221
255
  end
222
256
  end
223
257
  context 'with a filename blocked for read' do
224
- it 'should not be able to read the file' do
258
+ it 'raises an IOError' do
225
259
  expect(TCellAgent).to receive(:policy).with(
226
260
  TCellAgent::PolicyTypes::LFI
227
261
  ).and_return(@local_files_policy, @local_files_policy)
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  module TCellAgent
4
4
  module Instrumentation
5
5
  module Lfi
6
- describe 'extract path and mode' do
6
+ describe '.extract_path_mode' do
7
7
  context 'with path' do
8
8
  it 'should extract the path correctly' do
9
9
  args = '/path-to-file'
@@ -34,51 +34,91 @@ module TCellAgent
34
34
  args = '/path-to-file', 'r'
35
35
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
36
36
  expect(mode).to eq('Read')
37
+
38
+ args = '/path-to-file', { :mode => 'r' }
39
+ _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
40
+ expect(mode).to eq('Read')
37
41
  end
38
42
  it 'should return Write for mode w' do
39
43
  args = '/path-to-file', 'w'
40
44
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
41
45
  expect(mode).to eq('Write')
46
+
47
+ args = '/path-to-file', { :mode => 'w' }
48
+ _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
49
+ expect(mode).to eq('Write')
42
50
  end
43
51
  it 'should return Write for mode a' do
44
52
  args = '/path-to-file', 'a'
45
53
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
46
54
  expect(mode).to eq('Write')
55
+
56
+ args = '/path-to-file', { :mode => 'a' }
57
+ _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
58
+ expect(mode).to eq('Write')
47
59
  end
48
60
  it 'should return ReadWrite for mode r+' do
49
61
  args = '/path-to-file', 'r+'
50
62
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
51
63
  expect(mode).to eq('ReadWrite')
64
+
65
+ args = '/path-to-file', { :mode => 'r+' }
66
+ _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
67
+ expect(mode).to eq('ReadWrite')
52
68
  end
53
69
  it 'should return ReadWrite for mode w+' do
54
70
  args = '/path-to-file', 'w+'
55
71
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
56
72
  expect(mode).to eq('ReadWrite')
73
+
74
+ args = '/path-to-file', { :mode => 'w+' }
75
+ _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
76
+ expect(mode).to eq('ReadWrite')
57
77
  end
58
78
  it 'should return ReadWrite for mode a+' do
59
79
  args = '/path-to-file', 'a+'
60
80
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
61
81
  expect(mode).to eq('ReadWrite')
82
+
83
+ args = '/path-to-file', { :mode => 'a+' }
84
+ _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
85
+ expect(mode).to eq('ReadWrite')
62
86
  end
63
87
  it 'should return Read for mode ::File::RDONLY (0)' do
64
88
  args = '/path-to-file', ::File::RDONLY
65
89
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
66
90
  expect(mode).to eq('Read')
91
+
92
+ args = '/path-to-file', { :mode => ::File::RDONLY }
93
+ _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
94
+ expect(mode).to eq('Read')
67
95
  end
68
96
  it 'should return Write for mode ::File::WRONLY (1)' do
69
97
  args = '/path-to-file', ::File::WRONLY
70
98
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
71
99
  expect(mode).to eq('Write')
100
+
101
+ args = '/path-to-file', { :mode => ::File::WRONLY }
102
+ _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
103
+ expect(mode).to eq('Write')
72
104
  end
73
105
  it 'should return ReadWrite for mode ::File::RDWR (2)' do
74
106
  args = '/path-to-file', ::File::RDWR
75
107
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
76
108
  expect(mode).to eq('ReadWrite')
109
+
110
+ args = '/path-to-file', { :mode => ::File::RDWR }
111
+ _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
112
+ expect(mode).to eq('ReadWrite')
77
113
  end
78
114
  it 'should return Write for mode ::File::CREAT | ::File::EXCL | ::File::WRONLY (2561)' do
79
115
  args = '/path-to-file', ::File::CREAT | ::File::EXCL | ::File::WRONLY
80
116
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
81
117
  expect(mode).to eq('Write')
118
+
119
+ args = '/path-to-file', { :mode => ::File::CREAT | ::File::EXCL | ::File::WRONLY }
120
+ _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
121
+ expect(mode).to eq('Write')
82
122
  end
83
123
  end
84
124
  context 'with an invalid mode' do
@@ -87,11 +127,16 @@ module TCellAgent
87
127
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
88
128
  expect(mode).to eq('Read')
89
129
  end
90
- it 'should return Read when mode is a hash' do
130
+ it 'should return Read when mode is an empty hash' do
91
131
  args = '/path-to-file', {}
92
132
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
93
133
  expect(mode).to eq('Read')
94
134
  end
135
+ it 'should return Read when mode is a hash without a :mode key' do
136
+ args = '/path-to-file', { :placeholder => 'testing' }
137
+ _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
138
+ expect(mode).to eq('Read')
139
+ end
95
140
  it 'should return Read when mode is an array' do
96
141
  args = '/path-to-file', []
97
142
  _path, mode = TCellAgent::Instrumentation::Lfi.extract_path_mode(*args)
@@ -100,6 +145,79 @@ module TCellAgent
100
145
  end
101
146
  end
102
147
  end
148
+
149
+ describe '.raise_if_block' do
150
+ context 'when passed a blocked path' do
151
+ it 'raises an error' do
152
+ expect(TCellAgent::Instrumentation::Lfi).to receive(:block_file_access?).with(
153
+ '/blocked', 'Read'
154
+ ).and_return(true)
155
+
156
+ expect do
157
+ TCellAgent::Instrumentation::Lfi.raise_if_block('/blocked', 'Read')
158
+ end.to raise_error(IOError)
159
+ end
160
+ end
161
+ context 'when passed a path not blocked' do
162
+ it 'returns nil' do
163
+ expect(TCellAgent::Instrumentation::Lfi).to receive(:block_file_access?).with(
164
+ '/not-blocked', 'Read'
165
+ ).and_return(false)
166
+
167
+ expect(TCellAgent::Instrumentation::Lfi.raise_if_block('/not-blocked', 'Read')).to eq nil
168
+ end
169
+ end
170
+ end
171
+
172
+ describe '.default_open_handler' do
173
+ it 'calls .raise_if_block' do
174
+ expect(TCellAgent::Instrumentation::Lfi).to receive(:raise_if_block).with(
175
+ '/placeholder', 'Read'
176
+ ).and_return(nil)
177
+
178
+ expect(TCellAgent::Instrumentation::Lfi.default_open_handler(['/placeholder'], 'Read')).to eq nil
179
+ end
180
+
181
+ it 'replaces the mode with override_mode' do
182
+ expect(TCellAgent::Instrumentation::Lfi).to receive(:extract_path_mode).with(
183
+ '/placeholder'
184
+ ).and_return(['/placeholder', 'Read'])
185
+ expect(TCellAgent::Instrumentation::Lfi).to receive(:raise_if_block).with(
186
+ '/placeholder', 'ReadWrite'
187
+ ).and_return(nil)
188
+
189
+ expect(TCellAgent::Instrumentation::Lfi.default_open_handler(['/placeholder'], 'ReadWrite')).to eq nil
190
+ end
191
+ end
192
+
193
+ describe '.argf_open_handler' do
194
+ it 'calls .extract_path_mode_argf' do
195
+ expect(TCellAgent::Instrumentation::Lfi).to receive(:extract_path_mode_argf).and_return(
196
+ ['/placeholder', 'Read']
197
+ )
198
+
199
+ expect(TCellAgent::Instrumentation::Lfi.argf_open_handler).to eq nil
200
+ end
201
+ end
202
+ describe '.cmdi_open_handler' do
203
+ it 'behaves the similarly to default_open_handler' do
204
+ expect(TCellAgent::Instrumentation::Lfi).to receive(:raise_if_block).with(
205
+ '/placeholder', 'Read'
206
+ ).and_return(nil)
207
+
208
+ expect(TCellAgent::Instrumentation::Lfi.default_open_handler(['/placeholder'], 'Read')).to eq nil
209
+ end
210
+
211
+ it 'raises an error if command is blocked' do
212
+ expect(TCellAgent::Cmdi).to receive(:block_command?).with(
213
+ 'ls'
214
+ ).and_return(true)
215
+
216
+ expect do
217
+ TCellAgent::Instrumentation::Lfi.cmdi_open_handler('|ls')
218
+ end.to raise_error(RuntimeError)
219
+ end
220
+ end
103
221
  end
104
222
  end
105
223
  end
@@ -94,7 +94,8 @@ module TCellAgent
94
94
  'session_id',
95
95
  'user_id',
96
96
  'transaction_id',
97
- 'http://test.com/'
97
+ 'http://test.com/',
98
+ '0.0.0.0'
98
99
  )
99
100
  meta_data.get_dict = { 'paramater' => '<script>' }
100
101
  tcell_context = TCellAgent::Instrumentation::TCellData.new
@@ -1,4 +1,3 @@
1
-
2
1
  require 'spec_helper'
3
2
 
4
3
  module TCellAgent
@@ -44,7 +43,7 @@ module TCellAgent
44
43
  expect(@policy.enabled).to eq(true)
45
44
 
46
45
  expect(
47
- @policy.get_headers(@tcell_context)
46
+ @policy.get_headers('text/html', @tcell_context)
48
47
  ).to eq(
49
48
  [{ 'name' => 'Content-Security-Policy',
50
49
  'value' => "frame-ancestors 'none'; report-uri https://input.tcell-preview.io/csp/430d?sid=ab7074d0bf86c2884766d88b6ad9de4a&rid=route-id" }]
@@ -1,4 +1,3 @@
1
-
2
1
  require 'spec_helper'
3
2
 
4
3
  module TCellAgent
@@ -23,7 +22,7 @@ module TCellAgent
23
22
  expect(native_agent).to_not receive(:get_headers)
24
23
 
25
24
  tcell_context = double('tcell_context')
26
- policy.get_headers(tcell_context)
25
+ policy.get_headers('text/html', tcell_context)
27
26
  end
28
27
  end
29
28
 
@@ -65,7 +64,7 @@ module TCellAgent
65
64
  expect(@policy.enabled).to eq(true)
66
65
 
67
66
  expect(
68
- @policy.get_headers(@tcell_context)
67
+ @policy.get_headers('text/html', @tcell_context)
69
68
  ).to eq(
70
69
  [{ 'name' => 'Content-Security-Policy', 'value' => 'test321' }]
71
70
  )
@@ -92,7 +91,7 @@ module TCellAgent
92
91
  expect(@policy.enabled).to eq(true)
93
92
 
94
93
  expect(
95
- @policy.get_headers(@tcell_context)
94
+ @policy.get_headers('text/html', @tcell_context)
96
95
  ).to eq(
97
96
  [{ 'name' => 'Content-Security-Policy',
98
97
  'value' => 'normalvalue; report-uri https://www.example.com/xys?sid=ab7074d0bf86c2884766d88b6ad9de4a&rid=route-id' }]
@@ -121,7 +120,7 @@ module TCellAgent
121
120
  expect(@policy.enabled).to eq(true)
122
121
 
123
122
  expect(
124
- @policy.get_headers(@tcell_context)
123
+ @policy.get_headers('text/html', @tcell_context)
125
124
  ).to eq(
126
125
  [{ 'name' => 'Content-Security-Policy',
127
126
  'value' => 'normalvalue; report-uri https://www.example.com/1234567?sid=ab7074d0bf86c2884766d88b6ad9de4a&rid=route-id' }]
@@ -150,7 +149,7 @@ module TCellAgent
150
149
  expect(@policy.enabled).to eq(true)
151
150
 
152
151
  expect(
153
- @policy.get_headers(@tcell_context)
152
+ @policy.get_headers('text/html', @tcell_context)
154
153
  ).to eq([])
155
154
  end
156
155
  end
@@ -78,6 +78,8 @@ module TCellAgent
78
78
  meta_data = TCellAgent::Tests::MetaDataBuilder.new.update_attribute(
79
79
  'remote_address', nil
80
80
  ).build
81
+ expect(@native_agent).to receive(:apply_suspicious_quick_check).with(any_args)
82
+ expect(@native_agent).not_to receive(:apply_patches).with(any_args)
81
83
  resp = @policy.block_request?(meta_data)
82
84
  expect(resp).to eq(false)
83
85
  end
@@ -88,6 +90,8 @@ module TCellAgent
88
90
  meta_data = TCellAgent::Tests::MetaDataBuilder.new.update_attribute(
89
91
  'remote_address', ''
90
92
  ).build
93
+ expect(@native_agent).to receive(:apply_suspicious_quick_check).with(any_args)
94
+ expect(@native_agent).not_to receive(:apply_patches).with(any_args)
91
95
  resp = @policy.block_request?(meta_data)
92
96
  expect(resp).to eq(false)
93
97
  end
@@ -98,20 +102,35 @@ module TCellAgent
98
102
  meta_data = TCellAgent::Tests::MetaDataBuilder.new.update_attribute(
99
103
  'remote_address', '2.2.2.2'
100
104
  ).build
105
+ expect(@native_agent).to receive(:apply_suspicious_quick_check).with(any_args)
106
+ expect(@native_agent).not_to receive(:apply_patches).with(any_args)
101
107
  resp = @policy.block_request?(meta_data)
102
108
  expect(resp).to eq(false)
103
109
  end
104
110
  end
105
111
 
106
- context 'request comes from non-blocked ip' do
107
- it 'should not block request' do
112
+ context 'request comes from blocked ip' do
113
+ it 'should block request' do
108
114
  meta_data = TCellAgent::Tests::MetaDataBuilder.new.update_attribute(
109
115
  'remote_address', '1.1.1.1'
110
116
  ).build
117
+ expect(@native_agent).to receive(:apply_suspicious_quick_check).with(any_args).and_return(2)
118
+ expect(@native_agent).not_to receive(:apply_patches).with(any_args)
111
119
  resp = @policy.block_request?(meta_data)
112
120
  expect(resp).to eq(true)
113
121
  end
114
122
  end
123
+
124
+ context 'request comes from suspcious ip' do
125
+ it 'should call apply_patches' do
126
+ meta_data = TCellAgent::Tests::MetaDataBuilder.new.update_attribute(
127
+ 'remote_address', '1.1.1.1'
128
+ ).build
129
+ expect(@native_agent).to receive(:apply_suspicious_quick_check).with(any_args).and_return(1)
130
+ expect(@native_agent).to receive(:apply_patches).with(any_args).and_return('Blocked Response')
131
+ @policy.block_request?(meta_data)
132
+ end
133
+ end
115
134
  end
116
135
  end
117
136
  end
@@ -6,7 +6,7 @@ module TCellAgent
6
6
  assert_policy_state = proc do |policies, state|
7
7
  expect(policies.keys.size).to eq(10)
8
8
 
9
- policies.values.each do |policy|
9
+ policies.each_value do |policy|
10
10
  next if policy.instance_of?(TCellAgent::Policies::LoginPolicy)
11
11
  next if policy.instance_of?(TCellAgent::Policies::SystemEnablements)
12
12
 
@@ -1,4 +1,3 @@
1
-
2
1
  require 'spec_helper'
3
2
 
4
3
  module TCellAgent
@@ -16,13 +15,7 @@ module TCellAgent
16
15
  ).update_attribute(
17
16
  'route_id', 'route-id'
18
17
  ).build
19
- end
20
-
21
- after(:each) do
22
- TCellAgent::Rust::NativeAgent.free_agent(@native_agent.agent_ptr)
23
- end
24
18
 
25
- it 'should return csp header' do
26
19
  enablements = @native_agent.update_policies(
27
20
  {
28
21
  'secure-headers' => {
@@ -41,14 +34,26 @@ module TCellAgent
41
34
 
42
35
  @policy = HeadersPolicy.new(@native_agent, enablements)
43
36
  expect(@policy.enabled).to eq(true)
37
+ end
44
38
 
39
+ after(:each) do
40
+ TCellAgent::Rust::NativeAgent.free_agent(@native_agent.agent_ptr)
41
+ end
42
+
43
+ it 'should return csp header' do
45
44
  expect(
46
- @policy.get_headers(@tcell_context)
45
+ @policy.get_headers('text/html', @tcell_context)
47
46
  ).to eq(
48
47
  [{ 'name' => 'X-Content-Type-Options',
49
48
  'value' => 'nosniff' }]
50
49
  )
51
50
  end
51
+
52
+ it 'should not return csp header on json' do
53
+ expect(
54
+ @policy.get_headers('application/json', @tcell_context)
55
+ ).to eq([])
56
+ end
52
57
  end
53
58
  end
54
59
  end