cms_scanner 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c79b5986a23687749fae7044cd9c9828ef3b4b5b
4
- data.tar.gz: d22b1bf2c92efadbfe3dd6d34ce75b16130a6864
3
+ metadata.gz: b93921cef0886b572b23fb68c0eb79fc3ba4f99d
4
+ data.tar.gz: b77bf4aa78297bd4eee19634a8afb7a57db3b627
5
5
  SHA512:
6
- metadata.gz: 608ff3d5bcbfdca043e45756e30db9063469803b166aa1e4c8bda598c04217d732a500eeeec120dc32a4c743aa249e714c000fa13696bc523d3a4e800423d14e
7
- data.tar.gz: f4a77d3590ff7025e3e8f352715db124421a4f06ef56e46d68a9e01a2557049754085dadf623a0ebe466ef068ec10e22bea68308f0a3b23b0481df4a46ea67b0
6
+ metadata.gz: 00c2b526a36a7cd7f5b91861ab1a9d9ec990e584f0a09101b5fb8b992c42f2e7b5fb80eb5d0b97230f6f0ad9d68543bd4c0233256f13d1a6674ce91efdc40630
7
+ data.tar.gz: d9375a980fac1ddaed54c144dcffcec45251a5cb9c773a2d327852ebb8cecc3c8fddd9f373dc3fa502ffeef7acf03ebd0e4884b443626026fbb45e61356b08aa
@@ -14,7 +14,10 @@ module CMSScanner
14
14
  OptChoice.new(['--detection-mode MODE', 'Modes: mixed (default), passive, aggressive'],
15
15
  choices: %w(mixed passive aggressive),
16
16
  normalize: :to_sym,
17
- default: :mixed)
17
+ default: :mixed),
18
+ OptArray.new(['--scope DOMAINS',
19
+ 'Coma separated (sub-)domains to consider in scope. ' \
20
+ 'Wildcard(s) allowed in the trd of valid domains, e.g: *.target.tld'])
18
21
  ] + cli_browser_options
19
22
  end
20
23
 
data/cms_scanner.gemspec CHANGED
@@ -21,17 +21,18 @@ Gem::Specification.new do |s|
21
21
  s.test_files = s.files.grep(/^(test|spec|features)\//)
22
22
  s.require_path = 'lib'
23
23
 
24
- s.add_dependency 'opt_parse_validator', '~> 0.0.5'
24
+ s.add_dependency 'opt_parse_validator', '~> 0.0.6'
25
25
  s.add_dependency 'typhoeus', '~> 0.7'
26
- s.add_dependency 'nokogiri', '~> 1.6.3'
27
- s.add_dependency 'addressable', '~> 2.3.6'
28
- s.add_dependency 'activesupport', '~> 4.1'
26
+ s.add_dependency 'nokogiri', '~> 1.6'
27
+ s.add_dependency 'addressable', '~> 2.3'
28
+ s.add_dependency 'activesupport', '~> 4.2'
29
+ s.add_dependency 'public_suffix', '~> 1.4'
29
30
 
30
31
  s.add_development_dependency 'rake', '~> 10.4'
31
- s.add_development_dependency 'rspec', '~> 3.1'
32
+ s.add_development_dependency 'rspec', '~> 3.2'
32
33
  s.add_development_dependency 'rspec-its', '~> 1.1'
33
- s.add_development_dependency 'bundler', '~> 1.6'
34
+ s.add_development_dependency 'bundler', '~> 1.7'
34
35
  s.add_development_dependency 'rubocop', '~> 0.28'
35
- s.add_development_dependency 'webmock', '>= 1.18'
36
+ s.add_development_dependency 'webmock', '~> 1.20'
36
37
  s.add_development_dependency 'simplecov', '~> 0.9'
37
38
  end
data/lib/cms_scanner.rb CHANGED
@@ -4,13 +4,17 @@ require 'typhoeus'
4
4
  require 'nokogiri'
5
5
  require 'active_support/inflector'
6
6
  require 'addressable/uri'
7
+ require 'public_suffix'
7
8
  # Standard Libs
8
9
  require 'erb'
9
10
  require 'fileutils'
10
11
  require 'pathname'
11
- # Custom Libs
12
+ # Helpers
12
13
  require 'helper'
14
+ # Monkey Patches
13
15
  require 'cms_scanner/typhoeus/response'
16
+ require 'cms_scanner/public_suffix/domain'
17
+ # Custom Libs
14
18
  require 'cms_scanner/errors/auth_errors'
15
19
  require 'cms_scanner/cache/typhoeus'
16
20
  require 'cms_scanner/target'
@@ -19,7 +19,7 @@ module CMSScanner
19
19
 
20
20
  # @return [ Target ]
21
21
  def target
22
- @@target ||= NS::Target.new(parsed_options[:url])
22
+ @@target ||= NS::Target.new(parsed_options[:url], parsed_options)
23
23
  end
24
24
 
25
25
  # Set the parsed options and initialize the browser
@@ -0,0 +1,33 @@
1
+ module PublicSuffix
2
+ # Monkey Patch to include the match logic
3
+ class Domain
4
+ # For Sanity
5
+ def ==(other)
6
+ name == other.name
7
+ end
8
+
9
+ # TODO: better code for this method
10
+ # rubocop:disable all
11
+ def match(pattern)
12
+ pattern = PublicSuffix.parse(pattern) unless pattern.is_a?(PublicSuffix::Domain)
13
+
14
+ return name == pattern.name unless pattern.trd
15
+ return false unless tld == pattern.tld && sld == pattern.sld
16
+
17
+ pattern_trds = pattern.trd.split('.')
18
+ domain_trds = trd.split('.')
19
+
20
+ case pattern_trds.first
21
+ when '*'
22
+ pattern_trds[1..pattern_trds.size] == domain_trds[1..domain_trds.size]
23
+ when '**'
24
+ pa = pattern_trds[1..pattern_trds.size]
25
+
26
+ domain_trds[domain_trds.size - pa.size, pa.size] == pa
27
+ else
28
+ name == pattern.name
29
+ end
30
+ end
31
+ # rubocop:enable all
32
+ end
33
+ end
@@ -1,23 +1,41 @@
1
1
  require 'cms_scanner/web_site'
2
2
  require 'cms_scanner/target/platform'
3
3
  require 'cms_scanner/target/server'
4
+ require 'cms_scanner/target/scope'
4
5
 
5
6
  module CMSScanner
6
7
  # Target to Scan
7
8
  class Target < WebSite
8
9
  include Server::Generic
9
10
 
10
- # @note Subdomains are considered out of scope (maybe consider them in ?)
11
- # Also, // are handled by Addressable::URI, but worngly :/
12
- # e.g: Addressable::URI.parse('//file').host => file
11
+ # @param [ String ] url
12
+ # @param [ Hash ] opts
13
+ # @option opts [ Array<PublicSuffix::Domain, String> ] :scope
14
+ def initialize(url, opts = {})
15
+ super(url, opts)
16
+
17
+ scope << uri.host
18
+ [*opts[:scope]].each { |s| scope << s }
19
+ end
20
+
21
+ # @return [ Array<PublicSuffix::Domain, String> ]
22
+ def scope
23
+ @scope ||= Scope.new
24
+ end
25
+
26
+ # // are handled by Addressable::URI, but worngly :/
27
+ # e.g: Addressable::URI.parse('//file').host => file
28
+ #
29
+ # Idea: parse the // with PublicSuffix to see if a valid
30
+ # domain is used
13
31
  #
14
32
  # @param [ String ] url
15
33
  #
16
- # @return [ Boolean ] true if the url given belongs to the target
34
+ # @return [ Boolean ] true if the url given is in scope
17
35
  def in_scope?(url)
18
36
  return true if url[0, 1] == '/' && url[1, 1] != '/'
19
37
 
20
- Addressable::URI.parse(url).host == uri.host
38
+ scope.include?(Addressable::URI.parse(url).host)
21
39
  rescue
22
40
  false
23
41
  end
@@ -0,0 +1,37 @@
1
+ module CMSScanner
2
+ class Target < WebSite
3
+ # Scope Implementation
4
+ class Scope
5
+ # @return [ Array<PublicSuffix::Domain ] The valid domains in scope
6
+ def domains
7
+ @domains ||= []
8
+ end
9
+
10
+ # @return [ Array<String> ] The invalid domains in scope (such as IP addresses etc)
11
+ def invalid_domains
12
+ @invalid_domains ||= []
13
+ end
14
+
15
+ def <<(element)
16
+ if PublicSuffix.valid?(element)
17
+ domains << PublicSuffix.parse(element)
18
+ else
19
+ invalid_domains << element
20
+ end
21
+ end
22
+
23
+ # @return [ Boolean ] Wether or not the host is in the scope
24
+ def include?(host)
25
+ if PublicSuffix.valid?(host)
26
+ domain = PublicSuffix.parse(host)
27
+
28
+ domains.each { |d| return true if domain.match(d) }
29
+ else
30
+ invalid_domains.each { |d| return true if host == d }
31
+ end
32
+
33
+ false
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,4 +1,4 @@
1
1
  # Version
2
2
  module CMSScanner
3
- VERSION = '0.0.10'
3
+ VERSION = '0.0.11'
4
4
  end
@@ -1,10 +1,13 @@
1
1
  module CMSScanner
2
2
  # WebSite Implementation
3
3
  class WebSite
4
- attr_reader :uri
4
+ attr_reader :uri, :opts
5
5
 
6
- def initialize(site_url)
6
+ # @param [ String ] site_url
7
+ # @param [ Hash ] opts
8
+ def initialize(site_url, opts = {})
7
9
  self.url = site_url.dup
10
+ @opts = opts
8
11
  end
9
12
 
10
13
  def url=(site_url)
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe CMSScanner::Finders::InterestingFile::XMLRPC do
4
4
  subject(:finder) { described_class.new(target) }
5
5
  let(:target) { CMSScanner::Target.new(url) }
6
- let(:url) { 'http://ex.lo/' }
6
+ let(:url) { 'http://e.org/' }
7
7
  let(:xml_rpc_url) { url + 'xmlrpc.php' }
8
8
  let(:fixtures) { File.join(FIXTURES, 'interesting_files', 'xml_rpc') }
9
9
 
@@ -85,7 +85,7 @@ describe CMSScanner::Finders::InterestingFile::XMLRPC do
85
85
 
86
86
  context 'when URL is in scope' do
87
87
  let(:body) { File.new(File.join(fixtures, 'homepage_in_scope_pingback.html')).read }
88
- let(:expected_url) { 'http://ex.lo/wp/xmlrpc.php' }
88
+ let(:expected_url) { 'http://e.org/wp/xmlrpc.php' }
89
89
 
90
90
  it 'adds the URL to the #potential_urls and returns the XMLRPC' do
91
91
  result = finder.passive_body
@@ -42,7 +42,7 @@ describe CMSScanner::InterestingFile do
42
42
 
43
43
  context 'when not the same URL' do
44
44
  it 'returns false' do
45
- expect(file == described_class.new('http://ex.lo')).to be false
45
+ expect(file == described_class.new('http://e.org')).to be false
46
46
  end
47
47
  end
48
48
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'App::Views' do
4
- let(:target_url) { 'http://ex.lo/' }
4
+ let(:target_url) { 'http://e.org/' }
5
5
  let(:fixtures) { File.join(SPECS, 'output') }
6
6
 
7
7
  # CliNoColour is used to test the CLI output to avoid the painful colours
@@ -3,5 +3,5 @@
3
3
  <meta name="viewport" content="width=device-width">
4
4
  <title>WordPress 4.0 | Just another WordPress site</title>
5
5
  <link rel="profile" href="http://gmpg.org/xfn/11">
6
- <link rel="pingback" href="http://ex.lo/wp/xmlrpc.php">
6
+ <link rel="pingback" href="http://e.org/wp/xmlrpc.php">
7
7
  </head>
@@ -1,3 +1,3 @@
1
- <html><head><title>ex.lo - /dir/</title></head><body><H1>ex.lo - /dir/</H1><hr>
1
+ <html><head><title>e.org - /dir/</title></head><body><H1>e.org - /dir/</H1><hr>
2
2
 
3
3
  <pre>10/8/2014 11:00 PM &lt;dir&gt; <A HREF="/sub-dir/">sub-dir</A>10/10/2014 10:00 PM 168 <A HREF="/web.config">web.config</A><br></pre><hr></body></html>
@@ -1,3 +1,3 @@
1
- <html><head><title>ex.lo - /dir/</title></head><body><H1>ex.lo - /dir/</H1><hr>
1
+ <html><head><title>e.org - /dir/</title></head><body><H1>e.org - /dir/</H1><hr>
2
2
 
3
3
  <pre><A HREF="/">[To Parent Directory]</A><br><br> 10/8/2014 11:00 PM &lt;dir&gt; <A HREF="/sub-dir/">sub-dir</A>10/10/2014 10:00 PM 168 <A HREF="/web.config">web.config</A><br></pre><hr></body></html>
@@ -8,9 +8,10 @@ describe CMSScanner::Controller do
8
8
 
9
9
  let(:parsed_options) { { url: 'http://example.com/' } }
10
10
 
11
- its(:parsed_options) { should eq(parsed_options) }
12
- its(:formatter) { should be_a CMSScanner::Formatter::Cli }
13
- its(:target) { should be_a CMSScanner::Target }
11
+ its(:parsed_options) { should eq(parsed_options) }
12
+ its(:formatter) { should be_a CMSScanner::Formatter::Cli }
13
+ its(:target) { should be_a CMSScanner::Target }
14
+ its('target.scope.domains') { should eq [PublicSuffix.parse('example.com')] }
14
15
 
15
16
  describe '#render' do
16
17
  it 'calls the formatter#render' do
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe PublicSuffix::Domain do
4
+ describe '#match' do
5
+ it 'returns true' do
6
+ expect(PublicSuffix.parse('g.com').match('g.com')).to eql true
7
+ end
8
+
9
+ it 'returns true' do
10
+ expect(PublicSuffix.parse('s.g.com').match('*.g.com')).to eql true
11
+ end
12
+
13
+ it 'returns false' do
14
+ expect(PublicSuffix.parse('a.b.g.com').match('*.g.com')).to eql false
15
+ end
16
+
17
+ it 'returns true' do
18
+ expect(PublicSuffix.parse('a.b.g.com').match('*.b.g.com')).to eql true
19
+ end
20
+
21
+ it 'returns true' do
22
+ expect(PublicSuffix.parse('a.b.g.com').match('**.g.com')).to eql true
23
+ end
24
+
25
+ it 'returns false' do
26
+ expect(PublicSuffix.parse('a.b.y.g.com').match('**.b.g.com')).to eql false
27
+ end
28
+
29
+ it 'returns false' do
30
+ expect(PublicSuffix.parse('w.g.com').match('*.g2.com')).to eql false
31
+ end
32
+
33
+ it 'returns true' do
34
+ expect(PublicSuffix.parse('a.b.g.com').match('a.b.g.com')).to eql true
35
+ end
36
+
37
+ it 'returns false' do
38
+ expect(PublicSuffix.parse('a.b.g.com').match('a.y.g.com')).to eql false
39
+ end
40
+
41
+ it 'returns true' do
42
+ expect(PublicSuffix.parse('a.b.c.d.g.com').match('**.c.d.g.com')).to eql true
43
+ end
44
+
45
+ it 'returns true' do
46
+ expect(PublicSuffix.parse('a.b.c.d.g.com').match('*.b.c.d.g.com')).to eql true
47
+ end
48
+ end
49
+ end
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  subject(:target) do
6
6
  described_class.new(url).extend(described_class::Platform.const_get(platform))
7
7
  end
8
- let(:url) { 'http://ex.lo' }
8
+ let(:url) { 'http://e.org' }
9
9
  let(:fixtures) { File.join(FIXTURES, 'target', 'platform', platform.to_s.downcase) }
10
10
 
11
11
  it_behaves_like described_class::Platform.const_get(platform)
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  subject(:target) do
6
6
  described_class.new(url).extend(described_class::Server.const_get(server))
7
7
  end
8
- let(:url) { 'http://ex.lo' }
8
+ let(:url) { 'http://e.org' }
9
9
  let(:fixtures) { File.join(FIXTURES, 'target', 'server', server.to_s.downcase) }
10
10
 
11
11
  it_behaves_like described_class::Server.const_get(server)
@@ -1,23 +1,61 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CMSScanner::Target do
4
- subject(:target) { described_class.new(url) }
5
- let(:url) { 'http://ex.lo' }
4
+ subject(:target) { described_class.new(url, opts) }
5
+ let(:url) { 'http://e.org' }
6
+ let(:opts) { { scope: nil } }
7
+
8
+ describe '#scope' do
9
+ let(:default_domains) { [PublicSuffix.parse('e.org')] }
10
+
11
+ context 'when none supplied' do
12
+ its('scope.domains') { should eq default_domains }
13
+ end
14
+
15
+ context 'when scope provided' do
16
+ let(:opts) { super().merge(scope: ['*.e.org']) }
17
+
18
+ its('scope.domains') { should eq default_domains << PublicSuffix.parse(opts[:scope].first) }
19
+
20
+ context 'when invalid domains provided' do
21
+ let(:opts) { super().merge(scope: ['wp-lamp', '192.168.1.12']) }
22
+
23
+ it 'adds them in the invalid_domains attribute' do
24
+ expect(target.scope.domains).to eq default_domains
25
+ expect(target.scope.invalid_domains).to eq opts[:scope]
26
+ end
27
+ end
28
+ end
29
+ end
6
30
 
7
31
  describe '#in_scope?' do
8
- after { expect(target.in_scope?(@url)).to eq @expected }
32
+ context 'when default scope (target domain)' do
33
+ [nil, '', 'http://out-of-scope.com', '//jquery.com/j.js'].each do |url|
34
+ it "returns false for #{url}" do
35
+ expect(target.in_scope?(url)).to eql false
36
+ end
37
+ end
9
38
 
10
- [nil, '', 'http://out-of-scope.com', '//jquery.com/j.js'].each do |url|
11
- it "returns false for #{url}" do
12
- @url = url
13
- @expected = false
39
+ %w(https://e.org/file.txt http://e.org/ /relative).each do |url|
40
+ it "returns true for #{url}" do
41
+ expect(target.in_scope?(url)).to eql true
42
+ end
14
43
  end
15
44
  end
16
45
 
17
- %w(https://ex.lo/file.txt http://ex.lo/ /relative).each do |url|
18
- it "returns true for #{url}" do
19
- @url = url
20
- @expected = true
46
+ context 'when custom scope' do
47
+ let(:opts) { { scope: ['*.e.org', '192.168.1.12'] } }
48
+
49
+ [nil, '', 'http://out-of-scope.com', '//jquery.com/j.js', 'http://192.168.1.2/'].each do |url|
50
+ it "returns false for #{url}" do
51
+ expect(target.in_scope?(url)).to eql false
52
+ end
53
+ end
54
+
55
+ %w(https://cdn.e.org/file.txt http://www.e.org/ https://192.168.1.12/home).each do |url|
56
+ it "returns true for #{url}" do
57
+ expect(target.in_scope?(url)).to eql true
58
+ end
21
59
  end
22
60
  end
23
61
  end
@@ -1,8 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CMSScanner::WebSite do
4
- subject(:web_site) { described_class.new(url) }
5
- let(:url) { 'http://ex.lo' }
4
+ subject(:web_site) { described_class.new(url, opts) }
5
+ let(:url) { 'http://e.org' }
6
+ let(:opts) { {} }
6
7
 
7
8
  describe '#url=' do
8
9
  context 'when the url is incorrect' do
@@ -31,7 +32,7 @@ describe CMSScanner::WebSite do
31
32
 
32
33
  describe '#url' do
33
34
  context 'when no path argument' do
34
- its(:url) { should eql 'http://ex.lo/' }
35
+ its(:url) { should eql 'http://e.org/' }
35
36
  end
36
37
 
37
38
  context 'when a path argument' do
@@ -40,15 +41,25 @@ describe CMSScanner::WebSite do
40
41
  end
41
42
 
42
43
  context 'when relative path' do
43
- let(:url) { 'http://ex.lo/dir/' }
44
+ let(:url) { 'http://e.org/dir/' }
44
45
 
45
46
  it 'appends it from the host/domain' do
46
- expect(web_site.url('/sub/file.txt')).to eql 'http://ex.lo/sub/file.txt'
47
+ expect(web_site.url('/sub/file.txt')).to eql 'http://e.org/sub/file.txt'
47
48
  end
48
49
  end
49
50
  end
50
51
  end
51
52
 
53
+ describe '#opts' do
54
+ its(:opts) { should eql({}) }
55
+
56
+ context 'when opts' do
57
+ let(:opts) { { test: 'mm' } }
58
+
59
+ its(:opts) { should eql opts }
60
+ end
61
+ end
62
+
52
63
  describe '#online?, #http_auth?, #access_forbidden?, #proxy_auth?' do
53
64
  before { stub_request(:get, web_site.url(path)).to_return(status: status) }
54
65
 
@@ -1,3 +1,3 @@
1
- [+] URL: http://ex.lo/
1
+ [+] URL: http://e.org/
2
2
  [+] Started: Thu Oct 30 12:02:01 2014
3
3
 
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "start_time": 1414670521,
3
3
  "start_memory": 10,
4
- "target_url": "http://ex.lo/"
4
+ "target_url": "http://e.org/"
5
5
  }
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.10
4
+ version: 0.0.11
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-02-01 00:00:00.000000000 Z
11
+ date: 2015-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opt_parse_validator
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.0.5
19
+ version: 0.0.6
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.0.5
26
+ version: 0.0.6
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: typhoeus
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,42 +44,56 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.6.3
47
+ version: '1.6'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.6.3
54
+ version: '1.6'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: addressable
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 2.3.6
61
+ version: '2.3'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 2.3.6
68
+ version: '2.3'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: activesupport
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '4.1'
75
+ version: '4.2'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '4.1'
82
+ version: '4.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: public_suffix
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.4'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.4'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rake
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +114,14 @@ dependencies:
100
114
  requirements:
101
115
  - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: '3.1'
117
+ version: '3.2'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: '3.1'
124
+ version: '3.2'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: rspec-its
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +142,14 @@ dependencies:
128
142
  requirements:
129
143
  - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: '1.6'
145
+ version: '1.7'
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: '1.6'
152
+ version: '1.7'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: rubocop
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -154,16 +168,16 @@ dependencies:
154
168
  name: webmock
155
169
  requirement: !ruby/object:Gem::Requirement
156
170
  requirements:
157
- - - ">="
171
+ - - "~>"
158
172
  - !ruby/object:Gem::Version
159
- version: '1.18'
173
+ version: '1.20'
160
174
  type: :development
161
175
  prerelease: false
162
176
  version_requirements: !ruby/object:Gem::Requirement
163
177
  requirements:
164
- - - ">="
178
+ - - "~>"
165
179
  - !ruby/object:Gem::Version
166
- version: '1.18'
180
+ version: '1.20'
167
181
  - !ruby/object:Gem::Dependency
168
182
  name: simplecov
169
183
  requirement: !ruby/object:Gem::Requirement
@@ -251,9 +265,11 @@ files:
251
265
  - lib/cms_scanner/finders/unique_finders.rb
252
266
  - lib/cms_scanner/formatter.rb
253
267
  - lib/cms_scanner/formatter/buffer.rb
268
+ - lib/cms_scanner/public_suffix/domain.rb
254
269
  - lib/cms_scanner/target.rb
255
270
  - lib/cms_scanner/target/platform.rb
256
271
  - lib/cms_scanner/target/platform/php.rb
272
+ - lib/cms_scanner/target/scope.rb
257
273
  - lib/cms_scanner/target/server.rb
258
274
  - lib/cms_scanner/target/server/apache.rb
259
275
  - lib/cms_scanner/target/server/generic.rb
@@ -321,6 +337,7 @@ files:
321
337
  - spec/lib/finders/unique_finder_spec.rb
322
338
  - spec/lib/finders/unique_finders_spec.rb
323
339
  - spec/lib/formatter_spec.rb
340
+ - spec/lib/public_suffix/domain_spec.rb
324
341
  - spec/lib/sub_scanner_spec.rb
325
342
  - spec/lib/target/platforms_spec.rb
326
343
  - spec/lib/target/servers_spec.rb
@@ -431,6 +448,7 @@ test_files:
431
448
  - spec/lib/finders/unique_finder_spec.rb
432
449
  - spec/lib/finders/unique_finders_spec.rb
433
450
  - spec/lib/formatter_spec.rb
451
+ - spec/lib/public_suffix/domain_spec.rb
434
452
  - spec/lib/sub_scanner_spec.rb
435
453
  - spec/lib/target/platforms_spec.rb
436
454
  - spec/lib/target/servers_spec.rb