Back to Repositories

Testing RSS-based User Detection Implementation in WPScan

This test suite validates the RSSGenerator functionality in WPScan for discovering WordPress users through RSS feeds. It covers both passive and aggressive detection methods, ensuring reliable user enumeration through RSS feed analysis.

Test Coverage Overview

The test suite comprehensively covers RSS-based user detection scenarios in WordPress installations.

  • Tests both passive detection through homepage RSS links
  • Validates aggressive detection through common RSS feed paths
  • Handles cases with and without RSS links in homepage
  • Verifies mixed mode detection scenarios

Implementation Analysis

The implementation uses RSpec’s behavior-driven development approach with context-specific test cases.

Key patterns include:
  • Stub-based HTTP request mocking
  • Shared fixture loading for RSS feed data
  • Context-specific test scenarios using RSpec’s describe/context blocks
  • Confidence-based user detection validation

Technical Details

Testing infrastructure includes:
  • RSpec for test framework
  • WebMock for HTTP request stubbing
  • Fixture-based test data management
  • Custom WPScan model implementations
  • URL path validation and response handling

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Isolated test contexts for different scenarios
  • Comprehensive edge case coverage
  • Clear separation of passive and aggressive detection methods
  • Proper dependency stubbing and mocking
  • Consistent confidence level validation

wpscanteam/wpscan

spec/app/finders/users/rss_generator_spec.rb

            
# frozen_string_literal: true

describe WPScan::Finders::Users::RSSGenerator do
  subject(:finder)  { described_class.new(target) }
  let(:target)      { WPScan::Target.new(url) }
  let(:url)         { 'http://ex.lo/' }
  let(:fixtures)    { FINDERS_FIXTURES.join('users', 'rss_generator') }
  let(:rss_fixture) { File.read(fixtures.join('feed.xml')) }

  describe '#passive, #aggressive' do
    before do
      allow(target).to receive(:sub_dir).and_return(false)

      stub_request(:get, target.url).to_return(body: File.read(homepage_fixture))
    end

    context 'when no RSS link in homepage' do
      let(:homepage_fixture) { fixtures.join('homepage_no_links.html') }

      its(:passive) { should eql [] }

      it 'returns the expected from #aggressive' do
        stub_request(:get, target.url('feed/')).to_return(body: rss_fixture)
        stub_request(:get, target.url('comments/feed/'))
        stub_request(:get, target.url('feed/rss/'))
        stub_request(:get, target.url('feed/rss2/'))

        expect(finder.aggressive).to eql [
          WPScan::Model::User.new(
            'admin',
            confidence: 50,
            found_by: 'Rss Generator (Aggressive Detection)'
          ),
          WPScan::Model::User.new(
            'Aa Dias-Gildes',
            confidence: 50,
            found_by: 'Rss Generator (Aggressive Detection)'
          )
        ]
      end
    end

    context 'when RSS link in homepage' do
      let(:homepage_fixture) { fixtures.join('homepage_links.html') }

      it 'returns the expected from #passive' do
        stub_request(:get, target.url('feed/')).to_return(body: rss_fixture)

        expect(finder.passive).to eql [
          WPScan::Model::User.new(
            'admin',
            confidence: 50,
            found_by: 'Rss Generator (Passive Detection)'
          ),
          WPScan::Model::User.new(
            'Aa Dias-Gildes',
            confidence: 50,
            found_by: 'Rss Generator (Passive Detection)'
          )
        ]
      end

      context 'when :mixed mode' do
        it 'avoids checking existing URL/s from #passive' do
          stub_request(:get, target.url('comments/feed/')).to_return(body: rss_fixture)

          expect(finder.aggressive(mode: :mixed)).to eql [
            WPScan::Model::User.new(
              'admin',
              confidence: 50,
              found_by: 'Rss Generator (Aggressive Detection)'
            ),
            WPScan::Model::User.new(
              'Aa Dias-Gildes',
              confidence: 50,
              found_by: 'Rss Generator (Aggressive Detection)'
            )
          ]
        end
      end

      context 'when no mode' do
        it 'checks the first URL detected from the URLs' do
          stub_request(:get, target.url('feed/')).to_return(body: rss_fixture)

          expect(finder.aggressive).to eql [
            WPScan::Model::User.new(
              'admin',
              confidence: 50,
              found_by: 'Rss Generator (Aggressive Detection)'
            ),
            WPScan::Model::User.new(
              'Aa Dias-Gildes',
              confidence: 50,
              found_by: 'Rss Generator (Aggressive Detection)'
            )
          ]
        end
      end
    end
  end
end