New upstream version 0.0.40.3
Sophie Brun
5 years ago
64 | 64 | end |
65 | 65 | |
66 | 66 | def after_scan |
67 | @stop_time = Time.now | |
68 | @elapsed = @stop_time - @start_time | |
69 | @used_memory = memory_usage - @start_memory | |
70 | @requests_done = CMSScanner.total_requests | |
67 | @stop_time = Time.now | |
68 | @elapsed = @stop_time - @start_time | |
69 | @used_memory = memory_usage - @start_memory | |
71 | 70 | |
72 | output('finished') | |
71 | output('finished', | |
72 | cached_requests: NS.cached_requests, | |
73 | requests_done: NS.total_requests, | |
74 | data_sent: NS.total_data_sent, | |
75 | data_received: NS.total_data_received) | |
73 | 76 | end |
74 | 77 | end |
75 | 78 | end |
30 | 30 | @to_s || url |
31 | 31 | end |
32 | 32 | |
33 | # @return [ String ] | |
34 | def type | |
35 | @type ||= self.class.to_s.demodulize.underscore | |
36 | end | |
37 | ||
33 | 38 | # @return [ Boolean ] |
34 | 39 | def ==(other) |
35 | 40 | self.class == other.class && to_s == other.to_s |
0 | 0 | <%= info_icon %> Finished: <%= @stop_time.asctime %> |
1 | 1 | <%= info_icon %> Requests Done: <%= @requests_done %> |
2 | <%= info_icon %> Cached Requests: <%= @cached_requests %> | |
3 | <%= info_icon %> Data Sent: <%= @data_sent.bytes_to_human %> | |
4 | <%= info_icon %> Data Received: <%= @data_received.bytes_to_human %> | |
2 | 5 | <%= info_icon %> Memory used: <%= @used_memory.bytes_to_human %> |
3 | 6 | <%= info_icon %> Elapsed time: <%= Time.at(@elapsed).utc.strftime('%H:%M:%S') %> |
0 | 0 | "stop_time": <%= @stop_time.to_i %>, |
1 | 1 | "elapsed": <%= @elapsed.to_i %>, |
2 | 2 | "requests_done": <%= @requests_done.to_i %>, |
3 | "used_memory": <%= @used_memory.to_i %>,⏎ | |
3 | "cached_requests": <%= @cached_requests.to_i %>, | |
4 | "data_sent": <%= @data_sent.to_i %>, | |
5 | "data_sent_humanised": <%= @data_sent.bytes_to_human.to_json %>, | |
6 | "data_received": <%= @data_received.to_i %>, | |
7 | "data_received_humanised": <%= @data_received.bytes_to_human.to_json %>, | |
8 | "used_memory": <%= @used_memory.to_i %>, | |
9 | "used_memory_humanised": <%= @used_memory.bytes_to_human.to_json %>,⏎ |
4 | 4 | { |
5 | 5 | "url": <%= finding.url.to_s.to_json %>, |
6 | 6 | "to_s": <%= finding.to_s.to_json %>, |
7 | "type": <%= finding.type.to_json %>, | |
7 | 8 | "found_by": <%= finding.found_by.to_s.to_json %>, |
8 | 9 | "confidence": <%= finding.confidence.to_json %>, |
9 | 10 | "confirmed_by": { |
36 | 36 | s.add_development_dependency 'rake', '~> 12.3' |
37 | 37 | s.add_development_dependency 'rspec', '~> 3.8.0' |
38 | 38 | s.add_development_dependency 'rspec-its', '~> 1.2.0' |
39 | s.add_development_dependency 'rubocop', '~> 0.59.2' | |
39 | s.add_development_dependency 'rubocop', '~> 0.60.0' | |
40 | 40 | s.add_development_dependency 'simplecov', '~> 0.16.1' |
41 | 41 | s.add_development_dependency 'webmock', '~> 3.4.2' |
42 | 42 | end |
2 | 2 | module Platform |
3 | 3 | # Some PHP specific implementation |
4 | 4 | module PHP |
5 | DEBUG_LOG_PATTERN = /\[[^\]]+\] PHP (?:Warning|Error|Notice):/ | |
6 | FPD_PATTERN = /Fatal error:.+? in (.+?) on/ | |
7 | ERROR_LOG_PATTERN = /PHP Fatal error/i | |
5 | DEBUG_LOG_PATTERN = /\[[^\]]+\] PHP (?:Warning|Error|Notice):/.freeze | |
6 | FPD_PATTERN = /Fatal error:.+? in (.+?) on/.freeze | |
7 | ERROR_LOG_PATTERN = /PHP Fatal error/i.freeze | |
8 | 8 | |
9 | 9 | # @param [ String ] path |
10 | 10 | # @param [ Regexp ] pattern |
0 | 0 | module Typhoeus |
1 | 1 | # Custom Response class |
2 | 2 | class Response |
3 | # @return [ Nokogiri::HTML ] The response's body parsed by Nokogiri::HTML | |
3 | # @return [ Nokogiri::XML ] The response's body parsed by Nokogiri::HTML | |
4 | 4 | def html |
5 | 5 | @html ||= Nokogiri::HTML(body.encode('UTF-8', invalid: :replace, undef: :replace)) |
6 | 6 | end |
9 | 9 | def xml |
10 | 10 | @xml ||= Nokogiri::XML(body.encode('UTF-8', invalid: :replace, undef: :replace)) |
11 | 11 | end |
12 | ||
13 | # Override of the original to ensure an integer is returned | |
14 | # @return [ Integer ] | |
15 | def request_size | |
16 | super || 0 | |
17 | end | |
18 | ||
19 | # @return [ Integer ] | |
20 | def size | |
21 | (body.nil? ? 0 : body.size) + (response_headers.nil? ? 0 : response_headers.size) | |
22 | end | |
12 | 23 | end |
13 | 24 | end |
0 | 0 | # Version |
1 | 1 | module CMSScanner |
2 | VERSION = '0.0.40.2'.freeze | |
2 | VERSION = '0.0.40.3'.freeze | |
3 | 3 | end |
39 | 39 | APP_DIR = Pathname.new(__FILE__).dirname.join('..', 'app').expand_path |
40 | 40 | NS = self |
41 | 41 | |
42 | # Number of requests performed to display at the end of the scan | |
42 | # Number of requests performed and data sent/received to display at the end of the scan | |
43 | 43 | Typhoeus.on_complete do |response| |
44 | self.cached_requests += 1 if response.cached? | |
45 | ||
44 | 46 | next if response.cached? |
45 | 47 | |
46 | 48 | self.total_requests += 1 |
49 | self.total_data_sent += response.request_size | |
50 | self.total_data_received += response.size | |
47 | 51 | |
48 | 52 | NS::Browser.instance.trottle! |
49 | 53 | end |
52 | 56 | # is included in another module |
53 | 57 | module ClassMethods |
54 | 58 | # @return [ Integer ] |
59 | def cached_requests | |
60 | @@cached_requests ||= 0 | |
61 | end | |
62 | ||
63 | # @param [ Integer ] value | |
64 | def cached_requests=(value) | |
65 | @@cached_requests = value | |
66 | end | |
67 | ||
68 | # @return [ Integer ] | |
55 | 69 | def total_requests |
56 | 70 | @@total_requests ||= 0 |
57 | 71 | end |
58 | 72 | |
59 | # @param [ Integer ] | |
73 | # @param [ Integer ] value | |
60 | 74 | def total_requests=(value) |
61 | 75 | @@total_requests = value |
76 | end | |
77 | ||
78 | # @return [ Integer ] | |
79 | def total_data_sent | |
80 | @@total_data_sent ||= 0 | |
81 | end | |
82 | ||
83 | # @param [ Integer ] value | |
84 | def total_data_sent=(value) | |
85 | @@total_data_sent = value | |
86 | end | |
87 | ||
88 | # @return [ Integer ] | |
89 | def total_data_received | |
90 | @@total_data_received ||= 0 | |
91 | end | |
92 | ||
93 | # @param [ Integer ] value | |
94 | def total_data_received=(value) | |
95 | @@total_data_received = value | |
62 | 96 | end |
63 | 97 | |
64 | 98 | # The lowercase name of the scanner |
276 | 276 | end |
277 | 277 | |
278 | 278 | describe '#after_scan' do |
279 | let(:keys) { %i[verbose start_time stop_time start_memory elapsed used_memory] } | |
279 | let(:keys) do | |
280 | %i[verbose start_time stop_time start_memory elapsed used_memory requests_done data_sent data_received] | |
281 | end | |
280 | 282 | |
281 | 283 | it 'calls the formatter with the correct parameters' do |
282 | 284 | # Call the #run once to ensure that @start_time & @start_memory are set |
27 | 27 | describe '#references' do |
28 | 28 | its(:references) { should_not be_nil } |
29 | 29 | end |
30 | ||
31 | describe '#type' do | |
32 | its(:type) { should eql 'fantastico_fileslist' } | |
33 | end | |
30 | 34 | end |
47 | 47 | its(:interesting_entries) { should eq [] } |
48 | 48 | end |
49 | 49 | end |
50 | ||
51 | describe '#type' do | |
52 | its(:type) { should eql 'headers' } | |
53 | end | |
50 | 54 | end |
33 | 33 | end |
34 | 34 | end |
35 | 35 | end |
36 | end | |
37 | ||
38 | describe '#type' do | |
39 | its(:type) { should eql 'interesting_finding' } | |
36 | 40 | end |
37 | 41 | |
38 | 42 | describe '#entries' do |
23 | 23 | end |
24 | 24 | end |
25 | 25 | end |
26 | ||
27 | describe '#type' do | |
28 | its(:type) { should eql 'robots_txt' } | |
29 | end | |
26 | 30 | end |
3 | 3 | subject(:xml_rpc) { described_class.new(url) } |
4 | 4 | let(:url) { 'http://example.com/xmlrpc' } |
5 | 5 | let(:fixtures) { FIXTURES_MODELS.join('xml_rpc') } |
6 | ||
7 | describe '#type' do | |
8 | its(:type) { should eql 'xmlrpc' } | |
9 | end | |
6 | 10 | |
7 | 11 | describe '#method_call' do |
8 | 12 | after do |
8 | 8 | end |
9 | 9 | |
10 | 10 | describe 'typhoeus_on_complete' do |
11 | before { CMSScanner.total_requests = 0 } | |
11 | before do | |
12 | CMSScanner.cached_requests = 0 | |
13 | CMSScanner.total_requests = 0 | |
14 | CMSScanner.total_data_sent = 0 | |
15 | CMSScanner.total_data_received = 0 | |
16 | end | |
12 | 17 | |
13 | # TODO: find a way to test the cached requests which should not be counted | |
14 | 18 | it 'returns the expected number of requests' do |
15 | stub_request(:get, /.*/) | |
19 | stub_request(:get, /.*/).and_return(body: 'aa', headers: { 'key' => 'field' }) | |
16 | 20 | |
17 | 21 | CMSScanner::Browser.get(target_url) |
18 | 22 | |
23 | expect(CMSScanner.cached_requests).to eql 0 | |
19 | 24 | expect(CMSScanner.total_requests).to eql 1 |
25 | expect(CMSScanner.total_data_sent).to eql 0 # can't really test this one it seems | |
26 | expect(CMSScanner.total_data_received).to eql 29 | |
27 | end | |
28 | ||
29 | context 'when cached request' do | |
30 | it 'returns the expected values' do | |
31 | allow_any_instance_of(Typhoeus::Response).to receive(:cached?).and_return(true) | |
32 | ||
33 | stub_request(:get, target_url) | |
34 | ||
35 | CMSScanner::Browser.get(target_url) | |
36 | CMSScanner::Browser.get(target_url) | |
37 | ||
38 | expect(CMSScanner.cached_requests).to eql 2 | |
39 | expect(CMSScanner.total_requests).to eql 0 | |
40 | expect(CMSScanner.total_data_sent).to eql 0 | |
41 | expect(CMSScanner.total_data_received).to eql 0 | |
42 | end | |
20 | 43 | end |
21 | 44 | end |
22 | 45 |
0 | require 'spec_helper' | |
1 | ||
2 | describe Typhoeus::Response do | |
3 | subject(:response) { Typhoeus::Response.new(opts) } | |
4 | let(:opts) { { body: 'hello world' } } | |
5 | ||
6 | describe 'html' do | |
7 | its(:xml) { should be_a Nokogiri::XML::Document } | |
8 | end | |
9 | ||
10 | describe 'xml' do | |
11 | its(:xml) { should be_a Nokogiri::XML::Document } | |
12 | end | |
13 | ||
14 | describe 'request_size' do | |
15 | its(:request_size) { should eql 0 } | |
16 | end | |
17 | ||
18 | describe 'size' do | |
19 | context 'when no headers' do | |
20 | its(:size) { should eql 11 } | |
21 | end | |
22 | ||
23 | context 'when headers' do | |
24 | let(:opts) { super().merge(response_headers: "key: value\r\n") } | |
25 | ||
26 | its(:size) { should eql 23 } | |
27 | end | |
28 | end | |
29 | end |
0 | 0 | [+] Finished: Thu Oct 30 12:02:03 2014 |
1 | 1 | [+] Requests Done: 10 |
2 | [+] Cached Requests: 1 | |
3 | [+] Data Sent: 1000 B | |
4 | [+] Data Received: 1.953 KB | |
2 | 5 | [+] Memory used: 100 B |
3 | 6 | [+] Elapsed time: 00:00:02 |
1 | 1 | "stop_time": 1414670523, |
2 | 2 | "elapsed": 2, |
3 | 3 | "requests_done": 10, |
4 | "used_memory": 100 | |
4 | "cached_requests": 1, | |
5 | "data_sent": 1000, | |
6 | "data_sent_humanised": "1000 B", | |
7 | "data_received": 2000, | |
8 | "data_received_humanised": "1.953 KB", | |
9 | "used_memory": 100, | |
10 | "used_memory_humanised": "100 B" | |
5 | 11 | }⏎ |
0 | 0 | Interesting Finding(s): |
1 | 1 | |
2 | 2 | [+] F1_to_s |
3 | | Found By: Spec | |
3 | | Found By: Test (Passive) | |
4 | 4 | | Confidence: 10% |
5 | 5 | |
6 | 6 | [+] F2 |
2 | 2 | { |
3 | 3 | "url": "F1", |
4 | 4 | "to_s": "F1_to_s", |
5 | "found_by": "Spec", | |
5 | "type": "interesting_finding", | |
6 | "found_by": "Test (Passive)", | |
6 | 7 | "confidence": 10, |
7 | 8 | "confirmed_by": { |
8 | 9 | |
17 | 18 | { |
18 | 19 | "url": "F2", |
19 | 20 | "to_s": "F2", |
21 | "type": "interesting_finding", | |
20 | 22 | "found_by": "Spec", |
21 | 23 | "confidence": 20, |
22 | 24 | "confirmed_by": { |
36 | 38 | { |
37 | 39 | "url": "F3", |
38 | 40 | "to_s": "F3", |
41 | "type": "interesting_finding", | |
39 | 42 | "found_by": "Spec", |
40 | 43 | "confidence": 100, |
41 | 44 | "confirmed_by": { |
60 | 63 | { |
61 | 64 | "url": "F4", |
62 | 65 | "to_s": "F4", |
66 | "type": "interesting_finding", | |
63 | 67 | "found_by": "Spec", |
64 | 68 | "confidence": 0, |
65 | 69 | "confirmed_by": { |
50 | 50 | stop_time: Time.at(1_414_670_523).in_time_zone('Europe/London'), |
51 | 51 | used_memory: 100, |
52 | 52 | elapsed: 2, |
53 | requests_done: 10 | |
53 | requests_done: 10, | |
54 | cached_requests: 1, | |
55 | data_sent: 1000, | |
56 | data_received: 2000 | |
54 | 57 | ) |
55 | 58 | end |
56 | 59 | end |
18 | 18 | findings = CMSScanner::Finders::Findings.new |
19 | 19 | |
20 | 20 | findings << |
21 | interesting_file.new('F1', opts.merge(to_s: 'F1_to_s')) << | |
21 | interesting_file.new('F1', opts.merge(to_s: 'F1_to_s', found_by: 'Test (Passive)')) << | |
22 | 22 | interesting_file.new('F2', opts.merge(references: { url: 'R1' }, interesting_entries: %w[IE1])) << |
23 | 23 | interesting_file.new('F2', opts.merge(found_by: 'Spec2')) << |
24 | 24 | interesting_file.new('F3', |