cms_scanner 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|