Path: blob/master/spec/app/finders/users/wp_json_api_spec.rb
1483 views
# frozen_string_literal: true12describe WPScan::Finders::Users::WpJsonApi do3subject(:finder) { described_class.new(target) }4let(:target) { WPScan::Target.new(url) }5let(:url) { 'http://wp.lab/' }6let(:fixtures) { FINDERS_FIXTURES.join('users', 'wp_json_api') }78describe '#aggressive' do9before do10allow(target).to receive(:sub_dir).and_return(false)11allow(finder).to receive(:api_url).and_return(target.url('wp-json/wp/v2/users/'))12end1314context 'when only one page of results' do15before do16stub_request(:get, finder.api_url)17.with(query: { page: 1, per_page: 100 })18.to_return(body: body, headers: {})19end2021context 'when not a JSON response' do22let(:body) { '' }2324its(:aggressive) { should eql([]) }25end2627context 'when a JSON response' do28context 'when unauthorised' do29let(:body) { File.read(fixtures.join('401.json')) }3031its(:aggressive) { should eql([]) }32end3334context 'when limited exposure (WP >= 4.7.1)' do35let(:body) { File.read(fixtures.join('4.7.2.json')) }3637it 'returns the expected array of users' do38users = finder.aggressive3940expect(users.size).to eql 14142user = users.first4344expect(user.id).to eql 145expect(user.username).to eql 'admin'46expect(user.confidence).to eql 10047expect(user.interesting_entries).to eql ['http://wp.lab/wp-json/wp/v2/users/?page=1&per_page=100']48end49end50end51end5253context 'when multiple pages of results' do54before do55stub_request(:get, finder.api_url)56.with(query: { page: 1, per_page: 100 })57.to_return(body: File.read(fixtures.join('4.7.2.json')), headers: { 'X-WP-TotalPages' => 2 })5859stub_request(:get, finder.api_url)60.with(query: { page: 2, per_page: 100 })61.to_return(body: File.read(fixtures.join('4.7.2-2.json')), headers: { 'X-WP-TotalPages' => 2 })62end6364it 'returns the expected array of users' do65users = finder.aggressive6667expect(users.size).to eql 26869user = users.first7071expect(user.id).to eql 172expect(user.username).to eql 'admin'73expect(user.confidence).to eql 10074expect(user.interesting_entries).to eql ['http://wp.lab/wp-json/wp/v2/users/?page=1&per_page=100']7576user = users.second7778expect(user.id).to eql 2079expect(user.username).to eql 'user'80expect(user.confidence).to eql 10081expect(user.interesting_entries).to eql ['http://wp.lab/wp-json/wp/v2/users/?page=2&per_page=100']82end83end84end8586describe '#api_url' do87let(:fixtures) { super().join('api_url') }8889before { allow(target).to receive(:sub_dir).and_return(false) }9091context 'when url in the homepage' do92{93in_scope: 'https://wp.lab/wp-json/wp/v2/users/',94out_of_scope: 'http://wp.lab/wp-json/wp/v2/users/'95}.each do |fixture, expected|96it "returns #{expected} for #{fixture}.html" do97stub_request(:get, target.url).to_return(body: File.read(fixtures.join("#{fixture}.html")))9899expect(finder.api_url).to eql expected100end101end102103context 'when subdir' do104before { allow(target).to receive(:sub_dir).and_return('cms') }105106{107in_scope_subdir: 'https://wp.lab/cms/wp-json/wp/v2/users/',108in_scope_subdir_ignored: 'https://wp.lab/wp-json/wp/v2/users/'109}.each do |fixture, expected|110it "returns #{expected} for #{fixture}.html" do111stub_request(:get, target.url).to_return(body: File.read(fixtures.join("#{fixture}.html")))112113expect(finder.api_url).to eql expected114end115end116end117end118119context 'when not in the homepage' do120before { stub_request(:get, target.url) }121122its(:api_url) { should eql target.url('wp-json/wp/v2/users/') }123end124125context 'when api_url already found' do126before { allow(target).to receive(:sub_dir).and_return(false) }127128it 'does not check the homepage again' do129url = target.url('wp-json/wp/v2/users/')130131finder.instance_variable_set(:@api_url, url)132133expect(finder.api_url).to eql url134end135end136end137end138139140