Back to Repositories

Testing WordPress Config Backup Detection Implementation in WPScan

This test suite validates the functionality of the WPScan config backup file detection system, focusing on identifying WordPress configuration backup files through known filename patterns. The tests ensure reliable detection of potentially exposed configuration files that could pose security risks.

Test Coverage Overview

The test suite provides comprehensive coverage of the config backup finder functionality:

  • Tests both successful and unsuccessful backup file detection scenarios
  • Validates handling of multiple backup file formats
  • Verifies correct HTTP response processing
  • Tests URL encoding handling for special characters in filenames

Implementation Analysis

The testing approach utilizes RSpec’s behavior-driven development patterns with mock objects and stubbed HTTP requests. The implementation leverages context-specific test cases that validate the finder’s aggressive scanning mode, URL generation, and response handling.

  • Uses RSpec’s described_class pattern for maintainable test organization
  • Implements request stubbing for controlled HTTP response testing
  • Employs before blocks for shared test setup

Technical Details

  • RSpec test framework with WebMock for HTTP request stubbing
  • Fixture-based test data management
  • Custom matchers for response validation
  • Mock objects for target and finder instances
  • Configuration via external backup patterns file

Best Practices Demonstrated

The test suite exemplifies several testing best practices for security tools:

  • Isolation of external dependencies through mocking
  • Comprehensive edge case coverage
  • Clear test case organization and naming
  • Efficient test setup and teardown
  • Proper separation of concerns in test structure

wpscanteam/wpscan

spec/app/finders/config_backups/known_filenames_spec.rb

            
# frozen_string_literal: true

describe WPScan::Finders::ConfigBackups::KnownFilenames do
  subject(:finder) { described_class.new(target) }
  let(:target)     { WPScan::Target.new(url) }
  let(:url)        { 'http://ex.lo/' }
  let(:fixtures)   { FINDERS_FIXTURES.join('config_backups') }
  let(:opts)       { { list: WPScan::DB_DIR.join('config_backups.txt').to_s } }

  describe '#aggressive' do
    before do
      expect(target).to receive(:sub_dir).at_least(1).and_return(false)
      expect(target).to receive(:head_or_get_params).and_return(method: :head)

      finder.potential_urls(opts).each_key do |url|
        stub_request(:head, url).to_return(status: 404)
      end
    end

    context 'when all files are 404s' do
      it 'returns an empty array' do
        expect(finder.aggressive(opts)).to eql []
      end
    end

    context 'when some files exist' do
      let(:found_files) { ['%23wp-config.php%23', 'wp-config.bak'] }
      let(:config_backup) { File.read(fixtures.join('wp-config.php')) }

      before do
        found_files.each do |file|
          stub_request(:head, "#{url}#{file}").to_return(status: 200)
          stub_request(:get, "#{url}#{file}").to_return(status: 200, body: config_backup)
        end

        expect(target).to receive(:homepage_or_404?).twice.and_return(false)
      end

      it 'returns the expected Array<ConfigBackup>' do
        expected = []

        found_files.each do |file|
          url = "#{target.url}#{file}"

          expected << WPScan::Model::ConfigBackup.new(
            url,
            confidence: 100,
            found_by: described_class::DIRECT_ACCESS
          )
        end

        expect(finder.aggressive(opts)).to eql expected
      end
    end
  end
end