Back to Repositories

Testing PHP Execution Detection Workflow in WPScan

This test suite validates the PHP Disabled detection functionality in WPScan, focusing on identifying when PHP files are being served as plain text rather than executed. The tests ensure proper detection of disabled PHP processing in WordPress installations.

Test Coverage Overview

The test suite provides comprehensive coverage of PHP disabled detection scenarios:

  • Tests both successful and failed detection cases
  • Verifies response status code handling (200 vs 404)
  • Validates content matching for PHP file contents
  • Checks confidence level assignment for findings

Implementation Analysis

The testing approach utilizes RSpec’s behavior-driven development patterns with mock requests and response scenarios. The implementation leverages stub_request for HTTP interaction simulation and employs context-based test organization for different response conditions.

Technical Details

  • RSpec testing framework with shared contexts
  • Web request stubbing via WebMock
  • Fixture-based test data management
  • Apache server context simulation
  • HTTP method parameter handling

Best Practices Demonstrated

The test suite exemplifies several testing best practices including isolated test scenarios, proper mock object usage, and clear context separation. It demonstrates effective use of RSpec’s context blocks for different test conditions and proper stubbing of external dependencies.

wpscanteam/wpscan

spec/app/finders/interesting_findings/php_disabled_spec.rb

            
# frozen_string_literal: true

describe WPScan::Finders::InterestingFindings::PHPDisabled do
  subject(:finder) { described_class.new(target) }
  let(:target)     { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
  let(:url)        { 'http://ex.lo/' }
  let(:fixtures)   { FINDERS_FIXTURES.join('interesting_findings', 'php_disabled') }
  let(:file_path)  { 'wp-includes/version.php' }
  let(:file_url)   { target.url(file_path) }

  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)
    end

    context 'when not a 200' do
      it 'return nil' do
        stub_request(:head, file_url).to_return(status: 404)

        expect(finder.aggressive).to eql nil
      end
    end

    context 'when a 200' do
      before do
        stub_request(:head, file_url)
        stub_request(:get, file_url).to_return(body: body)
      end

      context 'when the body does not match' do
        let(:body) { '' }

        its(:aggressive) { should be_nil }
      end

      context 'when the body matches' do
        let(:body) { File.read(fixtures.join('version.php')) }

        it 'returns the PHPDisabled' do
          expect(finder.aggressive).to eql WPScan::Model::PHPDisabled.new(
            file_url,
            confidence: 100,
            found_by: described_class::DIRECT_ACCESS
          )
        end
      end
    end
  end
end