Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wpscanteam
GitHub Repository: wpscanteam/wpscan
Path: blob/master/spec/app/models/plugin_spec.rb
486 views
1
# frozen_string_literal: true
2
3
describe WPScan::Model::Plugin do
4
subject(:plugin) { described_class.new(slug, blog, opts) }
5
let(:slug) { 'spec' }
6
let(:blog) { WPScan::Target.new('http://wp.lab/') }
7
let(:opts) { {} }
8
9
before { expect(blog).to receive(:content_dir).and_return('wp-content') }
10
11
describe '#new' do
12
its(:url) { should eql 'http://wp.lab/wp-content/plugins/spec/' }
13
end
14
15
describe '#version' do
16
after do
17
expect(WPScan::Finders::PluginVersion::Base).to receive(:find).with(plugin, @expected_opts)
18
19
plugin.version(version_opts)
20
end
21
22
let(:default_opts) { {} }
23
24
context 'when no :detection_mode' do
25
context 'when no :mode opt supplied' do
26
let(:version_opts) { { something: 'k' } }
27
28
it 'calls the finder with the correct parameters' do
29
@expected_opts = version_opts
30
end
31
end
32
33
context 'when :mode supplied' do
34
let(:version_opts) { { mode: :passive } }
35
36
it 'calls the finder with the correct parameters' do
37
@expected_opts = default_opts.merge(mode: :passive)
38
end
39
end
40
end
41
42
context 'when :detection_mode' do
43
let(:opts) { super().merge(mode: :passive) }
44
45
context 'when no :mode' do
46
let(:version_opts) { {} }
47
48
it 'calls the finder without mode' do
49
@expected_opts = version_opts
50
end
51
end
52
53
context 'when :mode' do
54
let(:version_opts) { { mode: :mixed } }
55
56
it 'calls the finder with the :mixed mode' do
57
@expected_opts = default_opts.merge(mode: :mixed)
58
end
59
end
60
end
61
end
62
63
describe 'potential_readme_filenames' do
64
context 'when not set in the DF file' do
65
its(:potential_readme_filenames) { should eql described_class::READMES }
66
end
67
68
context 'when set in the DF file' do
69
context 'as a string' do
70
let(:slug) { 'photoblocks-grid-gallery' }
71
72
its(:potential_readme_filenames) { should eql %w[README.txt] }
73
end
74
75
context 'as an array' do
76
let(:slug) { 'customerlabs-actionrecorder' }
77
78
its(:potential_readme_filenames) { should eql %w[Readme.txt Readme.md] }
79
end
80
end
81
end
82
83
describe '#latest_version, #last_updated, #popular' do
84
before { allow(plugin).to receive(:db_data).and_return(db_data) }
85
86
context 'when no db_data and no metadata' do
87
let(:slug) { 'not-known' }
88
let(:db_data) { {} }
89
90
its(:latest_version) { should be_nil }
91
its(:last_updated) { should be_nil }
92
its(:popular?) { should be false }
93
end
94
95
context 'when no db_data but metadata' do
96
let(:slug) { 'no-vulns-popular' }
97
let(:db_data) { {} }
98
99
its(:latest_version) { should eql WPScan::Model::Version.new('2.0') }
100
its(:last_updated) { should eql '2015-05-16T00:00:00.000Z' }
101
its(:popular?) { should be true }
102
end
103
104
context 'when db_data' do
105
let(:slug) { 'no-vulns-popular' }
106
let(:db_data) { vuln_api_data_for('plugins/no-vulns-popular') }
107
108
its(:latest_version) { should eql WPScan::Model::Version.new('2.1') }
109
its(:last_updated) { should eql '2015-05-16T00:00:00.000Z-via-api' }
110
its(:popular?) { should be true }
111
end
112
end
113
114
describe '#outdated?' do
115
before { allow(plugin).to receive(:db_data).and_return({}) }
116
117
context 'when last_version' do
118
let(:slug) { 'no-vulns-popular' }
119
120
context 'when no version' do
121
before { expect(plugin).to receive(:version).at_least(1).and_return(nil) }
122
123
its(:outdated?) { should eql false }
124
end
125
126
context 'when version' do
127
before do
128
expect(plugin)
129
.to receive(:version)
130
.at_least(1)
131
.and_return(WPScan::Model::Version.new(version_number))
132
end
133
134
context 'when version < latest_version' do
135
let(:version_number) { '1.2' }
136
137
its(:outdated?) { should eql true }
138
end
139
140
context 'when version >= latest_version' do
141
let(:version_number) { '3.0' }
142
143
its(:outdated?) { should eql false }
144
end
145
end
146
end
147
148
context 'when no latest_version' do
149
let(:slug) { 'vulnerable-not-popular' }
150
151
context 'when no version' do
152
before { expect(plugin).to receive(:version).at_least(1).and_return(nil) }
153
154
its(:outdated?) { should eql false }
155
end
156
157
context 'when version' do
158
before do
159
expect(plugin)
160
.to receive(:version)
161
.at_least(1)
162
.and_return(WPScan::Model::Version.new('1.0'))
163
end
164
165
its(:outdated?) { should eql false }
166
end
167
end
168
end
169
170
describe '#vulnerabilities' do
171
before { allow(plugin).to receive(:db_data).and_return(db_data) }
172
173
after do
174
expect(plugin.vulnerabilities).to eq @expected
175
expect(plugin.vulnerable?).to eql !@expected.empty?
176
end
177
178
context 'when plugin not in the DB' do
179
let(:slug) { 'not-in-db' }
180
let(:db_data) { {} }
181
182
it 'returns an empty array' do
183
@expected = []
184
end
185
end
186
187
context 'when in the DB' do
188
context 'when no vulnerabilities' do
189
let(:slug) { 'no-vulns-popular' }
190
let(:db_data) { vuln_api_data_for('plugins/no-vulns-popular') }
191
192
it 'returns an empty array' do
193
@expected = []
194
end
195
end
196
197
context 'when vulnerabilities' do
198
context 'when only fixed_in' do
199
let(:slug) { 'vulnerable-not-popular' }
200
let(:db_data) { vuln_api_data_for('plugins/vulnerable-not-popular') }
201
202
let(:all_vulns) do
203
[
204
WPScan::Vulnerability.new(
205
'First Vuln <= 6.3.10 - LFI',
206
references: { wpvulndb: '1' },
207
type: 'LFI',
208
fixed_in: '6.3.10'
209
),
210
WPScan::Vulnerability.new('No Fixed In', references: { wpvulndb: '2' })
211
]
212
end
213
214
context 'when no plugin version' do
215
before { expect(plugin).to receive(:version).at_least(1).and_return(false) }
216
217
it 'returns all the vulnerabilities' do
218
@expected = all_vulns
219
end
220
end
221
222
context 'when plugin version' do
223
before do
224
expect(plugin)
225
.to receive(:version)
226
.at_least(1)
227
.and_return(WPScan::Model::Version.new(number))
228
end
229
230
context 'when < to fixed_in' do
231
let(:number) { '5.0' }
232
233
it 'returns it' do
234
@expected = all_vulns
235
end
236
end
237
238
context 'when >= to fixed_in' do
239
let(:number) { '6.3.10' }
240
241
it 'does not return it ' do
242
@expected = [all_vulns.last]
243
end
244
end
245
end
246
end
247
248
context 'when introduced_in' do
249
let(:db_data) { vuln_api_data_for('plugins/vulnerable-introduced-in') }
250
251
let(:all_vulns) do
252
[
253
WPScan::Vulnerability.new(
254
'Introduced In 6.4',
255
fixed_in: '6.5',
256
introduced_in: '6.4',
257
references: { wpvulndb: '1' }
258
)
259
]
260
end
261
262
context 'when no plugin version' do
263
before { expect(plugin).to receive(:version).at_least(1).and_return(false) }
264
265
it 'returns all the vulnerabilities' do
266
@expected = all_vulns
267
end
268
end
269
270
context 'when plugin version' do
271
before do
272
expect(plugin)
273
.to receive(:version)
274
.at_least(1)
275
.and_return(WPScan::Model::Version.new(number))
276
end
277
278
context 'when < to introduced_in' do
279
let(:number) { '5.0' }
280
281
it 'does not return it' do
282
@expected = []
283
end
284
end
285
286
context 'when >= to fixed_in' do
287
let(:number) { '6.5' }
288
289
it 'does not return it' do
290
@expected = []
291
end
292
end
293
294
context 'when >= to introduced_in' do
295
let(:number) { '6.4' }
296
297
it 'returns it' do
298
@expected = all_vulns
299
end
300
end
301
end
302
end
303
end
304
end
305
end
306
end
307
308