Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wpscanteam
GitHub Repository: wpscanteam/wpscan
Path: blob/master/spec/shared_examples/target/platform/wordpress.rb
485 views
1
# frozen_string_literal: true
2
3
require_relative 'wordpress/custom_directories'
4
5
shared_examples WPScan::Target::Platform::WordPress do
6
it_behaves_like 'WordPress::CustomDirectories'
7
8
let(:fixtures) { FIXTURES.join('target', 'platform', 'wordpress') }
9
10
describe '#wordpress?, wordpress_from_meta_comments_or_scripts?' do
11
let(:fixtures) { super().join('detection') }
12
13
before do
14
stub_request(:get, target.url).to_return(body: File.read(fixtures.join("#{homepage}.html")))
15
stub_request(:get, ERROR_404_URL_PATTERN).to_return(body: File.read(fixtures.join("#{page404}.html")))
16
end
17
18
context 'when pattern/s in the homepage' do
19
let(:page404) { 'not_wp' }
20
21
%w[default wp_includes only_scripts meta_generator comments mu_plugins wp_admin wp_json_oembed].each do |file|
22
context "when a wordpress page (#{file}.html)" do
23
let(:homepage) { file }
24
25
it 'returns true' do
26
expect(subject.wordpress?(:mixed)).to be true
27
end
28
end
29
end
30
end
31
32
context 'when no clues in the homepage' do
33
let(:homepage) { 'not_wp' }
34
35
context 'when pattern/s in the 404 page' do
36
%w[default wp_includes only_scripts meta_generator comments mu_plugins wp_admin wp_json_oembed].each do |file|
37
context "when a wordpress page (#{file}.html)" do
38
let(:page404) { file }
39
40
it 'returns true' do
41
expect(subject.wordpress?(:mixed)).to be true
42
end
43
end
44
end
45
end
46
47
context 'when no clues in the 404 page' do
48
let(:page404) { 'not_wp' }
49
50
context 'when only passive detection mode' do
51
it 'returns false' do
52
expect(subject.wordpress?(:passive)).to be false
53
end
54
end
55
56
context 'when mixed or aggressive detection modes' do
57
context 'when wp-admin/install.php and wp-login.php not there' do
58
it 'returns false' do
59
%w[wp-admin/install.php wp-login.php].each do |path|
60
stub_request(:get, target.url(path)).to_return(status: 404)
61
end
62
63
expect(subject.wordpress?(:mixed)).to be false
64
end
65
end
66
67
context 'when wp-admin/install.php is matching a WP install' do
68
it 'returns true' do
69
stub_request(:get, target.url('wp-admin/install.php'))
70
.to_return(body: File.read(fixtures.join('wp-admin-install.php')))
71
72
expect(subject.wordpress?(:mixed)).to be true
73
end
74
end
75
76
context 'when wp-admin/install.php not there but wp-login.php is matching a WP install' do
77
it 'returns true' do
78
stub_request(:get, target.url('wp-admin/install.php')).to_return(status: 404)
79
stub_request(:get, target.url('wp-login.php'))
80
.to_return(body: File.read(fixtures.join('wp-login.php')))
81
82
expect(subject.wordpress?(:mixed)).to be true
83
end
84
end
85
86
context 'when a lot of irrelevant links' do
87
let(:body) do
88
Array.new(250) do |i|
89
"<a href='#{subject.url}#{i}.html>Link</a><img src='#subject.{url}img-#{i}.png'/>"
90
end.join("\n")
91
end
92
93
it 'should not take a while to process check' do
94
stub_request(:get, target.url('wp-admin/install.php')).to_return(body: body)
95
stub_request(:get, target.url('wp-login.php')).to_return(body: body)
96
97
time_start = Time.now
98
expect(subject.wordpress?(:mixed)).to be false
99
time_end = Time.now
100
101
expect(time_end - time_start).to be < 1
102
end
103
end
104
end
105
end
106
end
107
end
108
109
describe '#maybe_add_cookies' do
110
let(:fixtures) { super().join('maybe_add_cookies') }
111
let(:browser) { WPScan::Browser.instance }
112
113
context 'when nothing matches' do
114
it 'does nothing' do
115
stub_request(:get, target.url).to_return(body: 'nothing there')
116
117
subject.maybe_add_cookies
118
119
expect(browser.cookie_string).to eql nil
120
expect(subject.homepage_res.body).to eql 'nothing there'
121
end
122
end
123
124
context 'when matches' do
125
before do
126
stub_request(:get, target.url)
127
.to_return(
128
{ body: File.read(fixtures.join("#{cookie}.html")) },
129
body: 'Cookies Accepted!' # if we put {} there, ruobop not happy!
130
)
131
end
132
133
{
134
'vjs' => 'vjs=2420671338'
135
}.each do |key, expected_cookie_string|
136
context "when #{key} match" do
137
let(:cookie) { key }
138
139
context 'when the browser does not have a cookie_string already' do
140
before do
141
subject.maybe_add_cookies
142
143
# This one does not work, opened an issue
144
# https://github.com/bblimke/webmock/issues/813
145
# stub_request(:get, target.url)
146
# .with(headers: { 'Cookie' => expected_cookie_string })
147
# .to_return(body: 'Cookies Accepted!')
148
end
149
150
it 'sets the correct cookies, reset the homepage_res' do
151
expect(browser.cookie_string).to eql expected_cookie_string
152
expect(subject.homepage_res.body).to eql 'Cookies Accepted!'
153
end
154
end
155
156
context 'when the browser has cookie_string already' do
157
before do
158
browser.cookie_string = 'key=no-override'
159
160
subject.maybe_add_cookies
161
162
# This one does not work, opened an issue
163
# https://github.com/bblimke/webmock/issues/813
164
# stub_request(:get, target.url)
165
# .with(headers: { 'Cookie' => "#{expected_cookie_string}; key=no-override" })
166
# .to_return(body: 'Cookies Accepted!')
167
end
168
169
it 'sets the correct cookies, reset the homepage_res' do
170
expect(browser.cookie_string).to eql "#{expected_cookie_string}; key=no-override"
171
expect(subject.homepage_res.body).to eql 'Cookies Accepted!'
172
end
173
end
174
end
175
end
176
end
177
end
178
179
describe '#wordpress_hosted?' do
180
let(:fixtures) { super().join('wordpress_hosted') }
181
182
context 'when the target host matches' do
183
let(:url) { 'http://ex.wordpress.com' }
184
185
its(:wordpress_hosted?) { should be true }
186
end
187
188
context 'when the target host doesn\'t matches' do
189
let(:url) { 'http://ex-wordpress.com' }
190
191
context 'when wp-content not detected' do
192
before do
193
expect(target).to receive(:content_dir).and_return(nil)
194
195
stub_request(:get, target.url)
196
.to_return(body: defined?(body) ? body : File.read(fixtures.join(fixture).to_s))
197
end
198
199
context 'when an src URL matches a WP hosted' do
200
let(:fixture) { 'match_src.html' }
201
202
its(:wordpress_hosted?) { should be true }
203
end
204
205
context 'when an href URL matches a WP hosted' do
206
let(:fixture) { 'match_href.html' }
207
208
its(:wordpress_hosted?) { should be true }
209
end
210
211
context 'when URLs don\'t match' do
212
let(:fixture) { 'no_match.html' }
213
214
its(:wordpress_hosted?) { should be false }
215
end
216
217
context 'when a lof of unrelated urls' do
218
let(:body) do
219
Array.new(250) { |i| "<a href='#{url}#{i}.html'>Some Link</a><img src='#{url}img-#{i}.png'/>" }.join("\n")
220
end
221
222
it 'should not take a while to process the page' do
223
time_start = Time.now
224
expect(target.wordpress_hosted?).to be false
225
time_end = Time.now
226
227
expect(time_end - time_start).to be < 1
228
end
229
end
230
end
231
232
context 'when wp-content detected' do
233
before { expect(target).to receive(:content_dir).and_return('wp-content') }
234
235
its(:wordpress_hosted?) { should be false }
236
end
237
end
238
end
239
240
describe '#login_url' do
241
before do
242
allow(target).to receive(:sub_dir)
243
244
WPScan::ParsedCli.options = rspec_parsed_options(cli_args)
245
end
246
247
let(:cli_args) { '--url https://ex.lo' }
248
249
context 'when login_uri CLI option set' do
250
let(:cli_args) { "#{super()} --login_uri other-login.php" }
251
252
its(:login_url) { should eql target.url('other-login.php') }
253
end
254
255
context 'when returning a 200' do
256
before { stub_request(:get, target.url('wp-login.php')).to_return(status: 200) }
257
258
its(:login_url) { should eql target.url('wp-login.php') }
259
end
260
261
context 'when a 404' do
262
before { stub_request(:get, target.url('wp-login.php')).to_return(status: 404) }
263
264
its(:login_url) { should eql false }
265
end
266
267
context 'when a redirection occured' do
268
before do
269
expect(WPScan::Browser).to receive(:get_and_follow_location)
270
.and_return(Typhoeus::Response.new(effective_url: effective_url, body: ''))
271
end
272
273
context 'to an in scope URL' do
274
context 'when https version of the wp-login' do
275
let(:effective_url) { target.url('wp-login.php').gsub('http', 'https') }
276
277
its(:login_url) { should eql effective_url }
278
end
279
280
context 'when something else' do
281
let(:effective_url) { target.url('something').gsub('http', 'https') }
282
283
its(:login_url) { should eql target.url('wp-login.php') }
284
end
285
end
286
287
context 'to an out of scope URL' do
288
let(:effective_url) { 'http://something.else' }
289
290
its(:login_url) { should eql target.url('wp-login.php') }
291
end
292
end
293
end
294
end
295
296