tcell_agent 2.0.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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