From 5bb9aa29faa711ff26ae106ba25c9719a0a8e88c Mon Sep 17 00:00:00 2001 From: erwanlr Date: Mon, 25 Mar 2013 15:24:46 +0100 Subject: [PATCH] WpItem::Infos specs --- lib/common/models/wp_item/infos.rb | 21 ++-- spec/lib/common/models/wp_item_spec.rb | 5 + .../models/wp_item}/error_log | 0 spec/shared_examples/wp_item_infos.rb | 109 ++++++++++++++++++ 4 files changed, 123 insertions(+), 12 deletions(-) rename spec/samples/{wpscan/wp_plugin/error_log => common/models/wp_item}/error_log (100%) create mode 100644 spec/shared_examples/wp_item_infos.rb diff --git a/lib/common/models/wp_item/infos.rb b/lib/common/models/wp_item/infos.rb index 7f27cbdd..e4c1f819 100644 --- a/lib/common/models/wp_item/infos.rb +++ b/lib/common/models/wp_item/infos.rb @@ -1,6 +1,8 @@ # encoding: UTF-8 class WpItem + + # @uri is used instead of #uri to avoid the presence of the :path into it module Infos # @return [ Boolean ] @@ -8,26 +10,17 @@ class WpItem Browser.instance.get(readme_url).code == 200 ? true : false end - # @return [ String ] + # @return [ String ] The url to the readme file def readme_url @uri.merge('readme.txt').to_s end - # @return [ String ] - def wordpress_url - - end - - def wordpress_org_item? - - end - # @return [ Boolean ] def has_changelog? Browser.instance.get(changelog_url).code == 200 ? true : false end - # @return [ String ] + # @return [ String ] The url to the changelog file def changelog_url @uri.merge('changelog.txt').to_s end @@ -43,16 +36,20 @@ class WpItem # however can also be found in their specific plugin dir. # http://www.exploit-db.com/ghdb/3714/ # + # Only the first 700 bytes are checked to avoid the download + # of the whole file which can be very huge (like 2 Go) + # # @return [ Boolean ] def has_error_log? response_body = Browser.instance.get(error_log_url, headers: {'range' => 'bytes=0-700'}).body response_body[%r{PHP Fatal error}i] ? true : false end - # @return [ String ] + # @return [ String ] The url to the error_log file def error_log_url @uri.merge('error_log').to_s end end + end diff --git a/spec/lib/common/models/wp_item_spec.rb b/spec/lib/common/models/wp_item_spec.rb index a869bdd4..9d1b48d5 100644 --- a/spec/lib/common/models/wp_item_spec.rb +++ b/spec/lib/common/models/wp_item_spec.rb @@ -5,6 +5,11 @@ require 'spec_helper' describe WpItem do it_behaves_like 'WpItem::Existable' it_behaves_like 'WpItem::Findable#Found_From=' + it_behaves_like 'WpItem::Infos' do + let(:readme_url) { uri.merge('readme.txt').to_s } + let(:changelog_url) { uri.merge('changelog.txt').to_s } + let(:error_log_url) { uri.merge('error_log').to_s } + end subject(:wp_item) { WpItem.new(uri, options) } let(:uri) { URI.parse('http://example.com') } diff --git a/spec/samples/wpscan/wp_plugin/error_log/error_log b/spec/samples/common/models/wp_item/error_log similarity index 100% rename from spec/samples/wpscan/wp_plugin/error_log/error_log rename to spec/samples/common/models/wp_item/error_log diff --git a/spec/shared_examples/wp_item_infos.rb b/spec/shared_examples/wp_item_infos.rb new file mode 100644 index 00000000..9b685a2e --- /dev/null +++ b/spec/shared_examples/wp_item_infos.rb @@ -0,0 +1,109 @@ +# encoding: UTF-8 + +shared_examples 'WpItem::Infos' do + + # 3 expected urls have to be set in the described class (or subject) + # e.g : + # let(:readme_url) { } + # let(:changelog_url) { } + # let(:error_log_url) { } + + describe '#readme_url' do + it 'returns the correct url' do + subject.readme_url.should == readme_url + end + end + + describe '#has_readme?' do + after :each do + stub_request(:get, subject.readme_url).to_return(status: @status) + subject.has_readme?.should === @expected + end + + it 'returns true on a 200' do + @status = 200 + @expected = true + end + + it 'returns false otherwise' do + @status = 404 + @expected = false + end + end + + describe '#changelog_url' do + it 'returns the correct url' do + subject.changelog_url.should == changelog_url + end + end + + describe '#has_changelog?' do + after :each do + stub_request(:get, subject.changelog_url).to_return(status: @status) + subject.has_changelog?.should === @expected + end + + it 'returns true on a 200' do + @status = 200 + @expected = true + end + + it 'returns false otherwise' do + @status = 404 + @expected = false + end + end + + describe '#has_directory_listing?' do + after do + stub_request(:get, subject.uri.to_s).to_return(@stub_return) + subject.has_directory_listing?.should === @expected + end + + context 'when the body contains Index of' do + it 'returns true' do + @stub_return = { status: 200, body: '<title>Index of asdf' } + @expected = true + end + end + + it 'returns false otherwise' do + @stub_return = { status: 200, body: 'My Wordpress Site' } + @expected = false + end + + it 'returns false on a 404' do + @stub_return = { status: 404 } + @expected = false + end + end + + describe '#error_log_url' do + it 'returns the correct url' do + subject.error_log_url.should == error_log_url + end + end + + describe '#has_error_log?' do + after do + stub_request(:get, subject.error_log_url).to_return(@stub_return) + subject.has_error_log?.should === @expected + end + + it 'returns true if the pattern is detected' do + @stub_return = { status: 200, body: File.new( MODELS_FIXTURES + '/wp_item/error_log') } + @expected = true + end + + it 'returns false otherwise' do + @stub_return = { status: 200, body: 'yolo' } + @expected = false + end + + it 'returns false on a 404' do + @stub_return = { status: 404 } + @expected = false + end + end + +end