cms_scanner 0.0.9 → 0.0.10
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.
- checksums.yaml +4 -4
- data/app/controllers/core.rb +1 -0
- data/lib/cms_scanner/errors/auth_errors.rb +8 -0
- data/lib/cms_scanner/target/platform.rb +0 -1
- data/lib/cms_scanner/version.rb +1 -1
- data/lib/cms_scanner/web_site.rb +25 -20
- data/spec/app/controllers/core_spec.rb +16 -1
- data/spec/lib/target/platforms_spec.rb +1 -1
- data/spec/lib/web_site_spec.rb +41 -58
- data/spec/shared_examples.rb +0 -1
- metadata +2 -20
- data/lib/cms_scanner/target/platform/wordpress.rb +0 -33
- data/lib/cms_scanner/target/platform/wordpress/custom_directories.rb +0 -61
- data/spec/fixtures/target/platform/wordpress/custom_directories/custom_w_spaces.html +0 -10
- data/spec/fixtures/target/platform/wordpress/custom_directories/default.html +0 -14
- data/spec/fixtures/target/platform/wordpress/custom_directories/https.html +0 -12
- data/spec/fixtures/target/platform/wordpress/detection/default.html +0 -4
- data/spec/fixtures/target/platform/wordpress/detection/not_wp.html +0 -8
- data/spec/fixtures/target/platform/wordpress/detection/wp_includes.html +0 -3
- data/spec/shared_examples/target/platform/wordpress.rb +0 -39
- data/spec/shared_examples/target/platform/wordpress/custom_directories.rb +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c79b5986a23687749fae7044cd9c9828ef3b4b5b
|
4
|
+
data.tar.gz: d22b1bf2c92efadbfe3dd6d34ce75b16130a6864
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 608ff3d5bcbfdca043e45756e30db9063469803b166aa1e4c8bda598c04217d732a500eeeec120dc32a4c743aa249e714c000fa13696bc523d3a4e800423d14e
|
7
|
+
data.tar.gz: f4a77d3590ff7025e3e8f352715db124421a4f06ef56e46d68a9e01a2557049754085dadf623a0ebe466ef068ec10e22bea68308f0a3b23b0481df4a46ea67b0
|
data/app/controllers/core.rb
CHANGED
@@ -18,6 +18,7 @@ module CMSScanner
|
|
18
18
|
|
19
19
|
fail "The url supplied '#{target.url}' seems to be down" unless target.online?
|
20
20
|
|
21
|
+
fail AccessForbiddenError if target.access_forbidden?
|
21
22
|
fail HTTPAuthRequiredError if target.http_auth?
|
22
23
|
fail ProxyAuthRequiredError if target.proxy_auth?
|
23
24
|
|
@@ -12,4 +12,12 @@ module CMSScanner
|
|
12
12
|
'Proxy authentication required (or was invalid), please provide it with --proxy-auth'
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
# Access Forbidden Error
|
17
|
+
class AccessForbiddenError < StandardError
|
18
|
+
def message
|
19
|
+
# TODO: add a --random-agent option
|
20
|
+
'The target is responding with a 403, this might be due to a WAF'
|
21
|
+
end
|
22
|
+
end
|
15
23
|
end
|
data/lib/cms_scanner/version.rb
CHANGED
data/lib/cms_scanner/web_site.rb
CHANGED
@@ -28,41 +28,46 @@ module CMSScanner
|
|
28
28
|
|
29
29
|
# Checks if the remote website is up.
|
30
30
|
#
|
31
|
+
# @param [ String ] path
|
32
|
+
#
|
31
33
|
# @return [ Boolean ]
|
32
|
-
def online?
|
33
|
-
NS::Browser.get(url).code != 0
|
34
|
+
def online?(path = nil)
|
35
|
+
NS::Browser.get(url(path)).code != 0
|
34
36
|
end
|
35
37
|
|
38
|
+
# @param [ String ] path
|
39
|
+
#
|
36
40
|
# @return [ Boolean ]
|
37
|
-
def http_auth?
|
38
|
-
NS::Browser.get(url).code == 401
|
41
|
+
def http_auth?(path = nil)
|
42
|
+
NS::Browser.get(url(path)).code == 401
|
39
43
|
end
|
40
44
|
|
45
|
+
# @param [ String ] path
|
46
|
+
#
|
41
47
|
# @return [ Boolean ]
|
42
|
-
def
|
43
|
-
NS::Browser.get(url).code ==
|
48
|
+
def access_forbidden?(path = nil)
|
49
|
+
NS::Browser.get(url(path)).code == 403
|
44
50
|
end
|
45
51
|
|
46
|
-
#
|
47
|
-
# This method is recursive
|
52
|
+
# @param [ String ] path
|
48
53
|
#
|
54
|
+
# @return [ Boolean ]
|
55
|
+
def proxy_auth?(path = nil)
|
56
|
+
NS::Browser.get(url(path)).code == 407
|
57
|
+
end
|
58
|
+
|
49
59
|
# @param [ String ] url
|
50
60
|
#
|
51
61
|
# @return [ String ] The redirection url or nil
|
62
|
+
#
|
63
|
+
# As webmock does not support redirects mocking, coverage is ignored
|
64
|
+
# :nocov:
|
52
65
|
def redirection(url = nil)
|
53
|
-
url
|
54
|
-
|
55
|
-
|
56
|
-
if response.code == 301 || response.code == 302
|
57
|
-
redirection = response.headers_hash['location']
|
58
|
-
|
59
|
-
# Let's check if there is a redirection in the redirection
|
60
|
-
if (other_redirection = redirection(redirection))
|
61
|
-
redirection = other_redirection
|
62
|
-
end
|
63
|
-
end
|
66
|
+
url ||= @uri.to_s
|
67
|
+
res = NS::Browser.get(url, followlocation: true)
|
64
68
|
|
65
|
-
|
69
|
+
res.effective_url == url ? nil : res.effective_url
|
66
70
|
end
|
71
|
+
# :nocov:
|
67
72
|
end
|
68
73
|
end
|
@@ -36,6 +36,12 @@ describe CMSScanner::Controller::Core do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
describe '#before_scan' do
|
39
|
+
it 'does not raise an error when everything is fine' do
|
40
|
+
stub_request(:get, target_url).to_return(status: 200)
|
41
|
+
|
42
|
+
expect { core.before_scan }.to_not raise_error
|
43
|
+
end
|
44
|
+
|
39
45
|
it 'raise an error when the site is down' do
|
40
46
|
stub_request(:get, target_url).to_return(status: 0)
|
41
47
|
|
@@ -46,13 +52,22 @@ describe CMSScanner::Controller::Core do
|
|
46
52
|
it 'raises an error when the site redirects' do
|
47
53
|
redirection = 'http://somewhere.com'
|
48
54
|
|
55
|
+
expect(core.target).to receive(:redirection).and_return(redirection)
|
56
|
+
|
49
57
|
stub_request(:get, target_url).to_return(status: 301, headers: { location: redirection })
|
50
|
-
stub_request(:get, redirection).to_return(status: 200)
|
51
58
|
|
52
59
|
expect { core.before_scan }
|
53
60
|
.to raise_error("The url supplied redirects to #{redirection}")
|
54
61
|
end
|
55
62
|
|
63
|
+
context 'when access is forbidden' do
|
64
|
+
before { stub_request(:get, target_url).to_return(status: 403) }
|
65
|
+
|
66
|
+
it 'raises an error' do
|
67
|
+
expect { core.before_scan }.to raise_error(CMSScanner::AccessForbiddenError)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
56
71
|
# This is quite a mess (as Webmock doesn't issue itself another 401
|
57
72
|
# when credential are incorrect :/)
|
58
73
|
context 'when http authentication' do
|
data/spec/lib/web_site_spec.rb
CHANGED
@@ -49,72 +49,55 @@ describe CMSScanner::WebSite do
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
describe '#online?' do
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
it { should be_http_auth }
|
71
|
-
end
|
72
|
-
|
73
|
-
context 'when no http auth' do
|
74
|
-
before { stub_request(:get, url).to_return(status: 200) }
|
75
|
-
|
76
|
-
it { should_not be_http_auth }
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
describe '#proxy_auth?' do
|
81
|
-
# Handled in app/controllers/core_spec
|
82
|
-
end
|
83
|
-
|
84
|
-
describe '#redirection' do
|
85
|
-
it 'returns nil if no redirection detected' do
|
86
|
-
stub_request(:get, web_site.url).to_return(status: 200, body: '')
|
87
|
-
|
88
|
-
expect(web_site.redirection).to be_nil
|
89
|
-
end
|
90
|
-
|
91
|
-
[301, 302].each do |status_code|
|
92
|
-
it "returns http://new-location.com if the status code is #{status_code}" do
|
93
|
-
new_location = 'http://new-location.com'
|
52
|
+
describe '#online?, #http_auth?, #access_forbidden?, #proxy_auth?' do
|
53
|
+
before { stub_request(:get, web_site.url(path)).to_return(status: status) }
|
54
|
+
|
55
|
+
[nil, 'file-path.txt'].each do |p|
|
56
|
+
context "when path = #{p}" do
|
57
|
+
let(:path) { p }
|
58
|
+
|
59
|
+
context 'when response status is a 200' do
|
60
|
+
let(:status) { 200 }
|
61
|
+
|
62
|
+
it 'is considered fine' do
|
63
|
+
expect(web_site.online?(path)).to be true
|
64
|
+
expect(web_site.http_auth?(path)).to be false
|
65
|
+
expect(web_site.access_forbidden?(path)).to be false
|
66
|
+
expect(web_site.proxy_auth?(path)).to be false
|
67
|
+
end
|
68
|
+
end
|
94
69
|
|
95
|
-
|
96
|
-
|
70
|
+
context 'when offline' do
|
71
|
+
let(:status) { 0 }
|
97
72
|
|
98
|
-
|
73
|
+
it 'returns false' do
|
74
|
+
expect(web_site.online?(path)).to be false
|
75
|
+
end
|
76
|
+
end
|
99
77
|
|
100
|
-
|
101
|
-
|
102
|
-
end
|
78
|
+
context 'when http auth required' do
|
79
|
+
let(:status) { 401 }
|
103
80
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
81
|
+
it 'returns true' do
|
82
|
+
expect(web_site.http_auth?(path)).to be true
|
83
|
+
end
|
84
|
+
end
|
108
85
|
|
109
|
-
|
110
|
-
|
86
|
+
context 'when access is forbidden' do
|
87
|
+
let(:status) { 403 }
|
111
88
|
|
112
|
-
|
113
|
-
|
89
|
+
it 'return true' do
|
90
|
+
expect(web_site.access_forbidden?(path)).to be true
|
91
|
+
end
|
92
|
+
end
|
114
93
|
|
115
|
-
|
94
|
+
context 'when proxy auth required' do
|
95
|
+
let(:status) { 407 }
|
116
96
|
|
117
|
-
|
97
|
+
it 'returns true' do
|
98
|
+
expect(web_site.proxy_auth?(path)).to be true
|
99
|
+
end
|
100
|
+
end
|
118
101
|
end
|
119
102
|
end
|
120
103
|
end
|
data/spec/shared_examples.rb
CHANGED
@@ -3,7 +3,6 @@ require 'shared_examples/formatter_buffer'
|
|
3
3
|
require 'shared_examples/formatter_class_methods'
|
4
4
|
require 'shared_examples/finding'
|
5
5
|
require 'shared_examples/independent_finder'
|
6
|
-
require 'shared_examples/target/platform/wordpress'
|
7
6
|
require 'shared_examples/target/platform/php'
|
8
7
|
require 'shared_examples/target/server/generic'
|
9
8
|
require 'shared_examples/target/server/apache'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cms_scanner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- WPScanTeam - Erwan Le Rousseau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01
|
11
|
+
date: 2015-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: opt_parse_validator
|
@@ -254,8 +254,6 @@ files:
|
|
254
254
|
- lib/cms_scanner/target.rb
|
255
255
|
- lib/cms_scanner/target/platform.rb
|
256
256
|
- lib/cms_scanner/target/platform/php.rb
|
257
|
-
- lib/cms_scanner/target/platform/wordpress.rb
|
258
|
-
- lib/cms_scanner/target/platform/wordpress/custom_directories.rb
|
259
257
|
- lib/cms_scanner/target/server.rb
|
260
258
|
- lib/cms_scanner/target/server/apache.rb
|
261
259
|
- lib/cms_scanner/target/server/generic.rb
|
@@ -298,12 +296,6 @@ files:
|
|
298
296
|
- spec/fixtures/output.txt
|
299
297
|
- spec/fixtures/target/platform/php/debug_log/debug.log
|
300
298
|
- spec/fixtures/target/platform/php/fpd/wp_rss_functions.php
|
301
|
-
- spec/fixtures/target/platform/wordpress/custom_directories/custom_w_spaces.html
|
302
|
-
- spec/fixtures/target/platform/wordpress/custom_directories/default.html
|
303
|
-
- spec/fixtures/target/platform/wordpress/custom_directories/https.html
|
304
|
-
- spec/fixtures/target/platform/wordpress/detection/default.html
|
305
|
-
- spec/fixtures/target/platform/wordpress/detection/not_wp.html
|
306
|
-
- spec/fixtures/target/platform/wordpress/detection/wp_includes.html
|
307
299
|
- spec/fixtures/target/server/apache/directory_listing/2.2.16.html
|
308
300
|
- spec/fixtures/target/server/generic/server/apache/basic.txt
|
309
301
|
- spec/fixtures/target/server/generic/server/iis/basic.txt
|
@@ -349,8 +341,6 @@ files:
|
|
349
341
|
- spec/shared_examples/formatter_class_methods.rb
|
350
342
|
- spec/shared_examples/independent_finder.rb
|
351
343
|
- spec/shared_examples/target/platform/php.rb
|
352
|
-
- spec/shared_examples/target/platform/wordpress.rb
|
353
|
-
- spec/shared_examples/target/platform/wordpress/custom_directories.rb
|
354
344
|
- spec/shared_examples/target/server/apache.rb
|
355
345
|
- spec/shared_examples/target/server/generic.rb
|
356
346
|
- spec/shared_examples/target/server/iis.rb
|
@@ -416,12 +406,6 @@ test_files:
|
|
416
406
|
- spec/fixtures/output.txt
|
417
407
|
- spec/fixtures/target/platform/php/debug_log/debug.log
|
418
408
|
- spec/fixtures/target/platform/php/fpd/wp_rss_functions.php
|
419
|
-
- spec/fixtures/target/platform/wordpress/custom_directories/custom_w_spaces.html
|
420
|
-
- spec/fixtures/target/platform/wordpress/custom_directories/default.html
|
421
|
-
- spec/fixtures/target/platform/wordpress/custom_directories/https.html
|
422
|
-
- spec/fixtures/target/platform/wordpress/detection/default.html
|
423
|
-
- spec/fixtures/target/platform/wordpress/detection/not_wp.html
|
424
|
-
- spec/fixtures/target/platform/wordpress/detection/wp_includes.html
|
425
409
|
- spec/fixtures/target/server/apache/directory_listing/2.2.16.html
|
426
410
|
- spec/fixtures/target/server/generic/server/apache/basic.txt
|
427
411
|
- spec/fixtures/target/server/generic/server/iis/basic.txt
|
@@ -467,8 +451,6 @@ test_files:
|
|
467
451
|
- spec/shared_examples/formatter_class_methods.rb
|
468
452
|
- spec/shared_examples/independent_finder.rb
|
469
453
|
- spec/shared_examples/target/platform/php.rb
|
470
|
-
- spec/shared_examples/target/platform/wordpress.rb
|
471
|
-
- spec/shared_examples/target/platform/wordpress/custom_directories.rb
|
472
454
|
- spec/shared_examples/target/server/apache.rb
|
473
455
|
- spec/shared_examples/target/server/generic.rb
|
474
456
|
- spec/shared_examples/target/server/iis.rb
|
@@ -1,33 +0,0 @@
|
|
1
|
-
%w(custom_directories).each do |required|
|
2
|
-
require "cms_scanner/target/platform/wordpress/#{required}"
|
3
|
-
end
|
4
|
-
|
5
|
-
module CMSScanner
|
6
|
-
class Target < WebSite
|
7
|
-
module Platform
|
8
|
-
# Some WordPress specific implementation
|
9
|
-
module WordPress
|
10
|
-
include PHP
|
11
|
-
|
12
|
-
WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|plugins|uploads))|wp-includes)/}i
|
13
|
-
|
14
|
-
def wordpress?
|
15
|
-
NS::Browser.get(url).html.css('script, link').each do |tag|
|
16
|
-
tag_url = tag.attribute('href').to_s
|
17
|
-
|
18
|
-
next unless in_scope?(tag_url)
|
19
|
-
|
20
|
-
tag_uri = Addressable::URI.parse(tag_url)
|
21
|
-
|
22
|
-
return true if tag_uri.path =~ WORDPRESS_PATTERN
|
23
|
-
end
|
24
|
-
false
|
25
|
-
end
|
26
|
-
|
27
|
-
def wordpress_hosted?
|
28
|
-
uri.host =~ /wordpress.com$/i ? true : false
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
module CMSScanner
|
2
|
-
class Target < WebSite
|
3
|
-
module Platform
|
4
|
-
# wp-content & plugins directory implementation
|
5
|
-
module WordPress
|
6
|
-
def content_dir=(dir)
|
7
|
-
@content_dir = dir.chomp('/')
|
8
|
-
end
|
9
|
-
|
10
|
-
def plugins_dir=(dir)
|
11
|
-
@plugins_dir = dir.chomp('/')
|
12
|
-
end
|
13
|
-
|
14
|
-
# @return [ String ] The wp-content directory
|
15
|
-
def content_dir
|
16
|
-
unless @content_dir
|
17
|
-
escaped_url = Regexp.escape(url).gsub(/https?/i, 'https?')
|
18
|
-
pattern = %r{#{escaped_url}(.+?)\/(?:themes|plugins|uploads)\/}i
|
19
|
-
|
20
|
-
NS::Browser.get(url).html.css('link,script,style,img').each do |tag|
|
21
|
-
%w(href src).each do |attribute|
|
22
|
-
attr_value = tag.attribute(attribute).to_s
|
23
|
-
|
24
|
-
next if attr_value.nil? || attr_value.empty?
|
25
|
-
next unless in_scope?(attr_value) && attr_value.match(pattern)
|
26
|
-
|
27
|
-
return @content_dir = Regexp.last_match[1]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
@content_dir
|
32
|
-
end
|
33
|
-
|
34
|
-
# @return [ Addressable::URI ]
|
35
|
-
def content_uri
|
36
|
-
uri.join("#{content_dir}/")
|
37
|
-
end
|
38
|
-
|
39
|
-
# @return [ String ]
|
40
|
-
def content_url
|
41
|
-
content_uri.to_s
|
42
|
-
end
|
43
|
-
|
44
|
-
# @return [ String ]
|
45
|
-
def plugins_dir
|
46
|
-
@plugins_dir ||= "#{content_dir}/plugins"
|
47
|
-
end
|
48
|
-
|
49
|
-
# @return [ Addressable::URI ]
|
50
|
-
def plugins_uri
|
51
|
-
uri.join("#{plugins_dir}/")
|
52
|
-
end
|
53
|
-
|
54
|
-
# @return [ String ]
|
55
|
-
def plugins_url
|
56
|
-
plugins_uri.to_s
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
<html dir="ltr" lang="en-US">
|
2
|
-
<head>
|
3
|
-
<meta charset="UTF-8" />
|
4
|
-
<meta name="viewport" content="width=device-width" />
|
5
|
-
<title>Wordpress 3.4.1 Custom | Just another WordPress site</title>
|
6
|
-
<link rel="profile" href="http://gmpg.org/xfn/11" />
|
7
|
-
<!-- This should not be detected as from another domain -->
|
8
|
-
<script src="http://another-domain/custom content spaces/themes/twentyeleven/js.js" />
|
9
|
-
|
10
|
-
<img src="http://ex.lo/custom content spaces/themes/twentyeleven/images/headers/pine-cone.jpg" width="1000" height="288" alt="" />
|
@@ -1,14 +0,0 @@
|
|
1
|
-
<html lang="en-US">
|
2
|
-
<head>
|
3
|
-
<meta charset="UTF-8">
|
4
|
-
<meta name="viewport" content="width=device-width">
|
5
|
-
<title>WordPress 4.0 | Just another WordPress site</title>
|
6
|
-
<link rel="profile" href="http://gmpg.org/xfn/11">
|
7
|
-
<link rel="pingback" href="http://ex.lo/xmlrpc.php">
|
8
|
-
<meta name='robots' content='noindex,follow' />
|
9
|
-
<link rel="alternate" type="application/rss+xml" title="Wordpress 4.0 » Feed" href="http://ex.lo/feed/" />
|
10
|
-
<link rel="alternate" type="application/rss+xml" title="Wordpress 4.0 » Comments Feed" href="http://ex.lo/comments/feed/" />
|
11
|
-
<link rel='stylesheet' id='twentyfourteen-lato-css' href='//fonts.googleapis.com/css?family=Lato%3A300%2C400%2C700%2C900%2C300italic%2C400italic%2C700italic' type='text/css' media='all' />
|
12
|
-
<link rel='stylesheet' id='flexSlider_stylesheet-css' href='http://ex.lo/wp-content/plugins/reflex-gallery/scripts/flexslider/flexslider.css?ver=4.0' type='text/css' media='all' />
|
13
|
-
<link rel='stylesheet' id='prettyPhoto_stylesheet-css' href='http://ex.lo/wp-content/plugins/reflex-gallery/scripts/prettyPhoto/prettyPhoto.css?ver=4.0' type='text/css' media='all' />
|
14
|
-
<link rel='stylesheet' id='genericons-css' href='http://ex.lo/wp-content/themes/twentyfourteen/genericons/genericons.css?ver=3.0.3' type='text/css'
|
@@ -1,12 +0,0 @@
|
|
1
|
-
<html lang="en-US">
|
2
|
-
<head>
|
3
|
-
<meta charset="UTF-8">
|
4
|
-
<meta name="viewport" content="width=device-width">
|
5
|
-
<title>WordPress 4.0 | Just another WordPress site</title>
|
6
|
-
<link rel="profile" href="http://gmpg.org/xfn/11">
|
7
|
-
<link rel="pingback" href="http://ex.lo/xmlrpc.php">
|
8
|
-
<meta name='robots' content='noindex,follow' />
|
9
|
-
<link rel="alternate" type="application/rss+xml" title="Wordpress 4.0 » Feed" href="http://ex.lo/feed/" />
|
10
|
-
<link rel="alternate" type="application/rss+xml" title="Wordpress 4.0 » Comments Feed" href="http://ex.lo/comments/feed/" />
|
11
|
-
<link rel='stylesheet' id='twentyfourteen-lato-css' href='//fonts.googleapis.com/css?family=Lato%3A300%2C400%2C700%2C900%2C300italic%2C400italic%2C700italic' type='text/css' media='all' />
|
12
|
-
<link rel='stylesheet' id='flexSlider_stylesheet-css' href='https://ex.lo/wp-content/plugins/reflex-gallery/scripts/flexslider/flexslider.css?ver=4.0' type='text/css' media='all' />
|
@@ -1,4 +0,0 @@
|
|
1
|
-
<meta name='robots' content='noindex,follow' />
|
2
|
-
<link rel='stylesheet' id='twentyfourteen-lato-css' href='//fonts.googleapis.com/css?family=Lato%3A300%2C400%2C700%2C900%2C300italic%2C400italic%2C700italic' type='text/css' media='all' />
|
3
|
-
<link rel='stylesheet' id='genericons-css' href='http://ex.lo/wordpress-4.0/wp-content/themes/twentyfourteen/genericons/genericons.css?ver=3.0.3' type='text/css' media='all' />
|
4
|
-
<link rel='stylesheet' id='twentyfourteen-style-css' href='http://ex.lo/wordpress-4.0/wp-content/themes/twentyfourteen/style.css?ver=4.0' type='text/css' media='all' />
|
@@ -1,8 +0,0 @@
|
|
1
|
-
<head>
|
2
|
-
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
3
|
-
<meta http-equiv="content-type" content="text/html; charset=UTF-8;charset=utf-8">
|
4
|
-
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=1" />
|
5
|
-
<meta name="HandheldFriendly" content="true"/>
|
6
|
-
|
7
|
-
<link rel="canonical" href="https://duckduckgo.com/">
|
8
|
-
|
@@ -1,3 +0,0 @@
|
|
1
|
-
<script type='text/javascript' src='http://ex.lo/wordpress-4.0/wp-includes/js/jquery/jquery.js?ver=1.11.1'></script>
|
2
|
-
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://ex.lo/wordpress-4.0/xmlrpc.php?rsd" />
|
3
|
-
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://ex.lo/wordpress-4.0/wp-includes/wlwmanifest.xml" />
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require_relative 'wordpress/custom_directories'
|
2
|
-
|
3
|
-
shared_examples CMSScanner::Target::Platform::WordPress do
|
4
|
-
it_behaves_like 'WordPress::CustomDirectories'
|
5
|
-
|
6
|
-
describe '#wordpress?' do
|
7
|
-
let(:fixtures) { File.join(super(), 'detection') }
|
8
|
-
|
9
|
-
before do
|
10
|
-
stub_request(:get, target.url).to_return(body: File.read(File.join(fixtures, "#{body}.html")))
|
11
|
-
end
|
12
|
-
|
13
|
-
%w(default wp_includes).each do |file|
|
14
|
-
context "when a wordpress page (#{file}.html)" do
|
15
|
-
let(:body) { file }
|
16
|
-
|
17
|
-
its(:wordpress?) { should be true }
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
%w(not_wp).each do |file|
|
22
|
-
context "when not a wordpress page (#{file}.html)" do
|
23
|
-
let(:body) { file }
|
24
|
-
|
25
|
-
its(:wordpress?) { should be false }
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe '#wordpress_hosted?' do
|
31
|
-
its(:wordpress_hosted?) { should be false }
|
32
|
-
|
33
|
-
context 'when the target host matches' do
|
34
|
-
let(:url) { 'http://ex.wordpress.com' }
|
35
|
-
|
36
|
-
its(:wordpress_hosted?) { should be true }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
|
2
|
-
shared_examples 'WordPress::CustomDirectories' do
|
3
|
-
let(:fixtures) { File.join(super(), 'custom_directories') }
|
4
|
-
|
5
|
-
describe '#content_dir' do
|
6
|
-
{
|
7
|
-
default: 'wp-content', https: 'wp-content', custom_w_spaces: 'custom content spaces'
|
8
|
-
}.each do |file, expected|
|
9
|
-
it "returns #{expected} for #{file}.html" do
|
10
|
-
fixture = File.join(fixtures, "#{file}.html")
|
11
|
-
|
12
|
-
stub_request(:get, target.url).to_return(body: File.read(fixture))
|
13
|
-
|
14
|
-
expect(target.content_dir).to eql expected
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe '#content_dir=, #plugins_dir=' do
|
20
|
-
['wp-content' 'wp-custom'].each do |dir|
|
21
|
-
context "when content_dir = #{dir} and no plugins_dir" do
|
22
|
-
before { target.content_dir = dir }
|
23
|
-
|
24
|
-
its(:content_dir) { should eq dir.chomp('/') }
|
25
|
-
its(:plugins_dir) { should eq dir.chomp('/') + '/plugins' }
|
26
|
-
end
|
27
|
-
|
28
|
-
context "when content_dir = #{dir} and plugins_dir = #{dir}" do
|
29
|
-
before do
|
30
|
-
target.content_dir = dir
|
31
|
-
target.plugins_dir = dir
|
32
|
-
end
|
33
|
-
|
34
|
-
its(:content_dir) { should eq dir.chomp('/') }
|
35
|
-
its(:plugins_dir) { should eq dir.chomp('/') }
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
describe '#content_uri, #content_url, #plugins_uri, #plugins_url' do
|
41
|
-
before { target.content_dir = 'wp-content' }
|
42
|
-
|
43
|
-
its(:content_uri) { should eq Addressable::URI.parse("#{url}/wp-content/") }
|
44
|
-
its(:content_url) { should eq "#{url}/wp-content/" }
|
45
|
-
|
46
|
-
its(:plugins_uri) { should eq Addressable::URI.parse("#{url}/wp-content/plugins/") }
|
47
|
-
its(:plugins_url) { should eq "#{url}/wp-content/plugins/" }
|
48
|
-
end
|
49
|
-
end
|