Codebase list ruby-cms-scanner / 84fd21c
New upstream version 0.7.1 Sophie Brun 4 years ago
21 changed file(s) with 159 addition(s) and 107 deletion(s). Raw diff Collapse all Expand all
44 - '*.gemspec'
55 - 'vendor/**/*'
66 - 'example/**/*'
7 ClassVars:
8 Enabled: false
9 LineLength:
10 Max: 120
11 MethodLength:
12 Max: 18
13 Exclude:
14 - app/controllers/core/cli_options.rb
157 Lint/UriEscapeUnescape:
168 Enabled: false
179 Metrics/AbcSize:
2113 - 'spec/**/*'
2214 Metrics/CyclomaticComplexity:
2315 Max: 10
16 Metrics/LineLength:
17 Max: 120
18 Metrics/MethodLength:
19 Max: 18
20 Exclude:
21 - app/controllers/core/cli_options.rb
2422 Metrics/PerceivedComplexity:
2523 Max: 9
24 Style/ClassVars:
25 Enabled: false
2626 Style/Documentation:
2727 Enabled: false
2828 Style/FormatStringToken:
77 - 2.4.4
88 - 2.4.5
99 - 2.4.6
10 - 2.4.7
11 - 2.4.8
12 - 2.4.9
1013 - 2.5.0
1114 - 2.5.1
1215 - 2.5.2
1316 - 2.5.3
1417 - 2.5.4
1518 - 2.5.5
19 - 2.5.6
20 - 2.5.7
1621 - 2.6.0
1722 - 2.6.1
1823 - 2.6.2
1924 - 2.6.3
20 - ruby-head
25 - 2.6.4
26 - 2.6.5
2127 before_install:
2228 - "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
2329 - gem update --system
24 matrix:
25 allow_failures:
26 - rvm: ruby-head
2730 script:
2831 - bundle exec rubocop
2932 - bundle exec rspec
6868 def after_scan
6969 @stop_time = Time.now
7070 @elapsed = @stop_time - @start_time
71 @used_memory = memory_usage - @start_memory
71 @used_memory = GetProcessMem.new.bytes - @start_memory
7272
7373 output('finished',
7474 cached_requests: NS.cached_requests,
1010 res = target.head_and_get(path)
1111
1212 return if res.body.strip.empty?
13 return unless res.headers && res.headers['Content-Type'] =~ %r{\Atext/plain}
13 return unless res.headers && res.headers['Content-Type']&.start_with?('text/plain')
1414
1515 NS::Model::FantasticoFileslist.new(target.url(path), confidence: 70, found_by: found_by)
1616 end
1818 s.test_files = []
1919 s.require_paths = ['lib']
2020
21 s.add_dependency 'get_process_mem', '~> 0.2.5'
2122 s.add_dependency 'nokogiri', '~> 1.10.4'
22 s.add_dependency 'opt_parse_validator', '~> 1.8.0'
23 s.add_dependency 'opt_parse_validator', '~> 1.8.1'
2324 s.add_dependency 'public_suffix', '>= 3.0', '< 4.1'
2425 s.add_dependency 'ruby-progressbar', '~> 1.10.0'
2526 s.add_dependency 'typhoeus', '~> 1.3.0'
2627 s.add_dependency 'xmlrpc', '~> 0.3'
2728 s.add_dependency 'yajl-ruby', '~> 1.4.1' # Better JSON parser regarding memory usage
2829
30 s.add_dependency 'sys-proctable', '~> 1.2.2' # Required by get_process_mem for Windows OS.
31
2932 s.add_development_dependency 'bundler', '>= 1.6'
3033 s.add_development_dependency 'coveralls', '~> 0.8.0'
31 s.add_development_dependency 'rake', '~> 12.3'
32 s.add_development_dependency 'rspec', '~> 3.8.0'
34 s.add_development_dependency 'rake', '~> 13.0'
35 s.add_development_dependency 'rspec', '~> 3.9.0'
3336 s.add_development_dependency 'rspec-its', '~> 1.3.0'
34 s.add_development_dependency 'rubocop', '~> 0.74.0'
35 s.add_development_dependency 'rubocop-performance', '~> 1.4.0'
37 s.add_development_dependency 'rubocop', '~> 0.76.0'
38 s.add_development_dependency 'rubocop-performance', '~> 1.5.0'
3639 s.add_development_dependency 'simplecov', '~> 0.16.1'
3740 s.add_development_dependency 'webmock', '~> 3.7.0'
3841 end
0 require: rubocop-performance
01 AllCops:
1 TargetRubyVersion: 2.3
2 TargetRubyVersion: 2.4
23 Exclude:
3 - '*.gemspec'
4 - 'vendor/**/*'
5 LineLength:
4 - '*.gemspec'
5 - 'vendor/**/*'
6 Metrics/AbcSize:
7 Max: 25
8 Metrics/CyclomaticComplexity:
9 Max: 10
10 Metrics/LineLength:
611 Max: 120
7 ClassVars:
12 Metrics/MethodLength:
13 Max: 17
14 Metrics/PerceivedComplexity:
15 Max: 9
16 Style/ClassVars:
817 Enabled: false
918 Style/RescueModifier:
1019 Enabled: false
1120 Style/SignalException:
1221 EnforcedStyle: semantic
13 MethodLength:
14 Max: 17
15 Metrics/AbcSize:
16 Max: 25
17 Metrics/CyclomaticComplexity:
18 Max: 10
19 Metrics/PerceivedComplexity:
20 Max: 9
11 sudo: false
22 cache: bundler
33 rvm:
4 - 2.3.0
5 - 2.3.1
6 - 2.3.2
7 - 2.3.3
8 - 2.3.4
9 - 2.3.5
10 - 2.3.6
11 - 2.3.7
12 - 2.3.8
13 - 2.4.1
14 - 2.4.2
15 - 2.4.3
16 - 2.4.4
17 - 2.4.5
18 - 2.5.0
19 - 2.5.1
20 - 2.5.2
21 - 2.5.3
22 - 2.6.0
4 - 2.4.9
5 - 2.5.7
6 - 2.6.5
237 - ruby-head
248 before_install:
259 - "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
2020 s.executables = ['cmsscan']
2121 s.require_paths = ['lib']
2222
23 s.add_dependency 'cms_scanner', '~> 0.0.44.1'
23 s.add_dependency 'cms_scanner', '~> 0.6.2'
2424
25 s.add_development_dependency 'bundler', '>= 1.6'
26 s.add_development_dependency 'coveralls', '~> 0.8.0'
27 s.add_development_dependency 'rake', '~> 12.3'
28 s.add_development_dependency 'rspec', '~> 3.8.0'
29 s.add_development_dependency 'rspec-its', '~> 1.2.0'
30 s.add_development_dependency 'rubocop', '~> 0.66.0'
31 s.add_development_dependency 'simplecov', '~> 0.16.1'
32 s.add_development_dependency 'webmock', '~> 3.5.1'
25 s.add_development_dependency 'bundler', '>= 1.6'
26 s.add_development_dependency 'coveralls', '~> 0.8.0'
27 s.add_development_dependency 'memory_profiler', '~> 0.9.13'
28 s.add_development_dependency 'rake', '~> 13.0'
29 s.add_development_dependency 'rspec', '~> 3.9.0'
30 s.add_development_dependency 'rspec-its', '~> 1.3.0'
31 s.add_development_dependency 'rubocop', '~> 0.76.0'
32 s.add_development_dependency 'rubocop-performance', '~> 1.5.0'
33 s.add_development_dependency 'simplecov', '~> 0.16.1'
34 s.add_development_dependency 'stackprof', '~> 0.2.12'
35 s.add_development_dependency 'webmock', '~> 3.7.0'
3336 end
1919
2020 # @return [ String ] The titleized name of the finder
2121 def titleize
22 self.class.to_s.demodulize.underscore.titleize
22 # Put a _ char before any digits except those at the end, which will be replaced by a space
23 # Otherwise, class such as Error404Page are returned as Error404 Page instead of Error 404 page
24 # The keep_id_suffix is to concevert classes such as CssId to Css Id instead of Css
25
26 @titleize ||= self.class.to_s.demodulize.gsub(/(\d+)[a-z]+/i, '_\0').titleize(keep_id_suffix: true)
2327 end
2428
2529 # @param [ Hash ] _opts
4953 @hydra ||= browser.hydra
5054 end
5155
52 # @param [ String, Symbol ] klass
56 # @param [String, Class ] klass
5357 # @return [ String ]
54 def found_by(klass = self)
58 def found_by(klass = self.class)
5559 caller_locations.each do |call|
5660 label = call.label
5761
5862 next unless %w[aggressive passive].include? label
5963
60 return "#{klass.titleize} (#{label.capitalize} Detection)"
64 title = klass.to_s.demodulize.gsub(/(\d+)[a-z]+/i, '_\0').titleize(keep_id_suffix: true)
65
66 return "#{title} (#{label.capitalize} Detection)"
6167 end
6268 nil
6369 end
44 $stdout.reopen(file, 'w')
55 $stdout.sync = true
66 end
7
8 # @return [ Integer ] The memory of the current process in Bytes
9 def memory_usage
10 `ps -o rss= -p #{Process.pid}`.to_i * 1024 # ps returns the value in KB
11 end
55 def bytes_to_human
66 units = %w[B KB MB GB TB]
77 e = abs.zero? ? abs : (Math.log(abs) / Math.log(1024)).floor
8 s = format('%.3f', (abs.to_f / 1024**e))
8 s = format('%<s>.3f', s: (abs.to_f / 1024**e))
99
1010 s.sub(/\.?0*$/, ' ' + units[e])
1111 end
55 attr_reader :run_error
66
77 def initialize
8 NS.start_memory = memory_usage
8 NS.start_memory = GetProcessMem.new.bytes
99
1010 controllers << NS::Controller::Core.new
1111
2626 # @note This is used to detect potential custom 404 responding with a 200
2727 # @return [ String ] The hash of a 404
2828 def error_404_hash
29 @error_404_hash ||= self.class.page_hash(non_existant_page_url)
30 end
31
32 # @return [ String ] The URL of an unlikely existant page
33 def non_existant_page_url
34 uri.join(Digest::MD5.hexdigest(rand(999_999_999).to_s) + '.html').to_s
29 @error_404_hash ||= self.class.page_hash(error_404_res)
3530 end
3631
3732 # @param [ Typhoeus::Response, String ] page
11
22 # Version
33 module CMSScanner
4 VERSION = '0.6.0'
4 VERSION = '0.7.1'
55 end
5252 # @return [ String ]
5353 def homepage_url
5454 @homepage_url ||= homepage_res.effective_url
55 end
56
57 # @return [ Typhoeus::Response ]
58 def error_404_res
59 @error_404_res ||= NS::Browser.get(error_404_url)
60 end
61
62 # @return [ String ] The URL of an unlikely existant page
63 def error_404_url
64 @error_404_url ||= non_existant_page_url
65 end
66
67 # @return [ String ] The URL of an unlikely existant page
68 # TODO: This will be removed in the next major version (0.7)
69 def non_existant_page_url
70 uri.join(Digest::MD5.hexdigest(rand(999_999).to_s)[0..6] + '.html').to_s
5571 end
5672
5773 # Checks if the remote website is up.
55 require 'yajl/json_gem'
66 require 'public_suffix'
77 require 'addressable/uri'
8 require 'get_process_mem'
89 require 'ruby-progressbar'
910 require 'opt_parse_validator'
1011 require 'active_support/concern'
3030 end
3131 end
3232
33 context 'when no Content-Type header' do
34 it 'return nil' do
35 stub_request(:get, file_url)
36 .to_return(status: 200, body: 'not empty', headers: {})
37
38 expect(finder.aggressive).to eql nil
39 end
40 end
41
3342 context 'when not a text/plain Content-Type' do
3443 it 'return nil' do
3544 stub_request(:get, file_url)
36 .to_return(status: 200, body: 'not empty', headers: { 'Content-Type' => 'text/html ' })
45 .to_return(status: 200, body: 'not empty', headers: { 'Content-Type' => 'text/html' })
3746
3847 expect(finder.aggressive).to eql nil
3948 end
11
22 describe CMSScanner::Finders::Finder do
33 subject(:finder) { described_class.new('target') }
4
5 its(:titleize) { should eql 'Finder' }
6 its(:browser) { should be_a CMSScanner::Browser }
7 its(:hydra) { should be_a Typhoeus::Hydra }
48
59 describe '#create_progress_bar' do
610 before { finder.create_progress_bar(opts) }
3943 end
4044 end
4145
42 its(:browser) { should be_a CMSScanner::Browser }
46 class SpecCallerLocation
47 attr_reader :call
4348
44 its(:hydra) { should be_a Typhoeus::Hydra }
49 def initialize(call)
50 @call = call
51 end
52
53 def label
54 @label ||= call[/`([^']+)'$/, 1]
55 end
56
57 def to_s
58 call
59 end
60 end
4561
4662 describe '#found_by' do
4763 context 'when no klass supplied' do
5369 end
5470 end
5571
56 # TODO: make the below work
57 # context 'when aggressive match' do
58 # it 'returns the expected string' do
59 # expect(finder).to receive(:caller_locations)
60 # .and_return([Thread::Backtrace::Location.new("/aaaaa/file.rb:xx:in `aggressive'")])
61 #
62 # expect(finder.found_by).to eql 'Finder (Aggressive Detection)'
63 # end
64 # end
72 context 'when aggressive match' do
73 it 'returns the expected string' do
74 expect(finder).to receive(:caller_locations)
75 .and_return([SpecCallerLocation.new("/aaaaa/file.rb:xx:in `aggressive'")])
76
77 expect(finder.found_by).to eql 'Finder (Aggressive Detection)'
78 end
79 end
6580 end
6681
67 # context 'when class supplied' do
68 # it 'returns the expected string' do
69 # expect(finder).to receive(:caller_locations)
70 # .and_return(["/aaaaa/file.rb:xx:in `passive'"])
71 #
72 # expect(finder.found_by('Rspec')).to eql 'Rspec (Passive Detection)'
73 # end
74 # end
82 {
83 Rspec: 'Rspec', Error404Page: 'Error 404 Page',
84 CssId: 'Css Id', Something12Db2: 'Something 12 Db2'
85 }.each do |klass, expected_title|
86 context "when class #{klass} supplied" do
87 it 'returns the expected string' do
88 allow(finder).to receive(:caller_locations)
89 .and_return([SpecCallerLocation.new("/aaaaa/file.rb:xx:in `passive'")])
90
91 expected = "#{expected_title} (Passive Detection)"
92
93 # klass = Object.const_set(klass_name, Class.new(described_class))
94
95 expect(finder.found_by(klass)).to eql expected
96 end
97 end
98 end
7599 end
76100 end
6666
6767 describe '#error_404_hash' do
6868 it 'returns the md5sum of the 404 page' do
69 stub_request(:any, /.*/).to_return(status: 404, body: '404 page !')
69 stub_request(:any, ERROR_404_URL_PATTERN).to_return(status: 404, body: '404 page !')
7070
7171 expect(target.error_404_hash).to eql md5sum('404 page !')
7272 end
6060 expect(web_site.url('/sub/file.txt')).to eql 'http://e.org/sub/file.txt'
6161 end
6262 end
63 end
64 end
65
66 describe '#error_404_url' do
67 its(:error_404_url) { should match ERROR_404_URL_PATTERN }
68
69 it 'returns the same url when called more than once' do
70 url1 = web_site.error_404_url
71 url2 = web_site.error_404_url
72
73 expect(url1).to eql url2
6374 end
6475 end
6576
7777 end
7878 # rubocop:enabled all
7979
80 SPECS = Pathname.new(__FILE__).dirname
81 CACHE = SPECS.join('cache')
82 FIXTURES = SPECS.join('fixtures')
83 FIXTURES_VIEWS = FIXTURES.join('views')
84 FIXTURES_FINDERS = FIXTURES.join('finders')
85 FIXTURES_MODELS = FIXTURES.join('models')
86 FIXTURES_CONTROLLERS = FIXTURES.join('controllers')
87 APP_VIEWS = File.join(CMSScanner::APP_DIR, 'views')
80 SPECS = Pathname.new(__FILE__).dirname
81 CACHE = SPECS.join('cache')
82 FIXTURES = SPECS.join('fixtures')
83 FIXTURES_VIEWS = FIXTURES.join('views')
84 FIXTURES_FINDERS = FIXTURES.join('finders')
85 FIXTURES_MODELS = FIXTURES.join('models')
86 FIXTURES_CONTROLLERS = FIXTURES.join('controllers')
87 APP_VIEWS = File.join(CMSScanner::APP_DIR, 'views')
88 ERROR_404_URL_PATTERN = %r{/[a-z\d]{7}\.html$}