Path: blob/master/spec/lib/finders/dynamic_finder/plugin_version_spec.rb
1466 views
# frozen_string_literal: true12# All Plugin Dynamic Finders returning a Version are tested here.3# When adding one to the spec/fixtures/db/dynamic_finder.yml, a few files have4# to be edited/created5#6# - spec/fixtures/dynamic_finder/expected.yml with the expected result/s7# - Then, depending on the finder class used: spec/fixtures/dynamic_finder/plugin_version/8#9# Furthermore, the fixtures files _passive_all.html are also used by plugins/themes10# finders in spec/app/finders/plugins|themes to check the items existence from the homepage11#12# In case of a failure, it's recommended to use rspec -e "<Full Description>" while fixing.13# e.g: rspec -e "WPScan::Finders::PluginVersion::Cardealerpress::HeaderPattern#passive"14# The -e option can also be used to test all HeaderPattern, for example: rspec -e "::HeaderPattern"1516expected_all = df_expected_all['plugins']1718WPScan::DB::DynamicFinders::Plugin.versions_finders_configs.each do |slug, configs|19WPScan::DB::DynamicFinders::Plugin.create_versions_finders(slug)2021configs.each do |finder_class, config|22finder_super_class = config['class'] || finder_class2324# The QueryParameter specs are slow given the huge fixture file25# If someone find a fix for that, please share!26describe df_tested_class_constant('PluginVersion', finder_class, slug), slow: true do27subject(:finder) { described_class.new(plugin) }28let(:plugin) { WPScan::Model::Plugin.new(slug, target) }29let(:target) { WPScan::Target.new('http://wp.lab/') }30let(:fixtures) { DYNAMIC_FINDERS_FIXTURES.join('plugin_version') }3132let(:expected) do33if expected_all[slug][finder_class].is_a?(Hash)34[expected_all[slug][finder_class]]35else36expected_all[slug][finder_class]37end38end3940before { allow(target).to receive(:content_dir).and_return('wp-content') }4142describe '#passive', slow: true do43before do44if defined?(stubbed_homepage_res)45stub_request(:get, target.url).to_return(stubbed_homepage_res)46else47stub_request(:get, target.url)48end4950if defined?(stubbed_404_res)51stub_request(:get, ERROR_404_URL_PATTERN).to_return(stubbed_404_res)52else53stub_request(:get, ERROR_404_URL_PATTERN)54end55end5657if config['path']58context 'when PATH' do59it 'returns nil' do60expect(finder.passive).to eql nil61end62end63else64context 'when no PATH' do65context 'when the version is detected' do66context 'from the homepage' do67let(:ie_url) { target.url }68let(:stubbed_homepage_res) do69df_stubbed_response(70fixtures.join("#{finder_super_class.underscore}_passive_all.html"),71finder_super_class72)73end7475it 'returns the expected version/s' do76found = Array(finder.passive)7778expect(found).to_not be_empty7980found.each_with_index do |version, index|81expected_version = expected.at(index)82expected_ie = expected_version['interesting_entries'].map do |ie|83ie.gsub("#{target.url},", "#{ie_url},")84end8586expect(version).to be_a WPScan::Model::Version87expect(version.number).to eql expected_version['number'].to_s88expect(version.found_by).to eql expected_version['found_by']89expect(version.interesting_entries).to match_array expected_ie9091expect(version.confidence).to eql expected_version['confidence'] if expected_version['confidence']92end93end94end9596context 'from the 404' do97let(:ie_url) { target.error_404_url }98let(:stubbed_404_res) do99df_stubbed_response(100fixtures.join("#{finder_super_class.underscore}_passive_all.html"),101finder_super_class102)103end104105it 'returns the expected version/s' do106found = Array(finder.passive)107108expect(found).to_not be_empty109110found.each_with_index do |version, index|111expected_version = expected.at(index)112expected_ie = expected_version['interesting_entries'].map do |ie|113ie.gsub("#{target.url},", "#{ie_url},")114end115116expect(version).to be_a WPScan::Model::Version117expect(version.number).to eql expected_version['number'].to_s118expect(version.found_by).to eql expected_version['found_by']119expect(version.interesting_entries).to match_array expected_ie120121expect(version.confidence).to eql expected_version['confidence'] if expected_version['confidence']122end123end124end125end126127context 'when the version is not detected' do128it 'returns nil or an empty array' do129expect(finder.passive).to eql finder_super_class == 'QueryParameter' ? [] : nil130end131end132end133end134end135136describe '#aggressive' do137let(:fixtures) { super().join(slug, finder_class.underscore) }138let(:stubbed_response) { { body: 'aa' } }139140before do141stub_request(:get, plugin.url(config['path'])).to_return(stubbed_response) if config['path']142end143144if config['path']145context 'when the version is detected' do146let(:stubbed_response) do147df_stubbed_response(fixtures.join(config['path']), finder_super_class)148end149150it 'returns the expected version' do151found = Array(finder.aggressive)152153expect(found).to_not be_empty154155found.each_with_index do |version, index|156expected_version = expected.at(index)157158expect(version).to be_a WPScan::Model::Version159expect(version.number).to eql expected_version['number'].to_s160expect(version.found_by).to eql expected_version['found_by']161expect(version.interesting_entries).to match_array expected_version['interesting_entries']162163expect(version.confidence).to eql expected_version['confidence'] if expected_version['confidence']164end165end166end167168context 'when the version is not detected' do169it 'returns nil or an empty array' do170expect(finder.aggressive).to eql finder_super_class == 'QueryParameter' ? [] : nil171end172end173else174it 'returns nil' do175expect(finder.aggressive).to eql nil176end177end178end179end180end181end182183184