From f09606cfa3ee56a0fac22715313d8e98038b0059 Mon Sep 17 00:00:00 2001 From: erwanlr Date: Wed, 20 Mar 2019 15:21:02 +0000 Subject: [PATCH] Fixes #1319 --- app/finders/users/wp_json_api.rb | 10 +++- spec/app/finders/users/wp_json_api_spec.rb | 55 ++++++++++++++++++- .../users/wp_json_api/api_url/in_scope.html | 1 + .../wp_json_api/api_url/in_scope_subdir.html | 6 ++ .../api_url/in_scope_subdir_ignored.html | 6 ++ .../wp_json_api/api_url/out_of_scope.html | 1 + 6 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 spec/fixtures/finders/users/wp_json_api/api_url/in_scope.html create mode 100644 spec/fixtures/finders/users/wp_json_api/api_url/in_scope_subdir.html create mode 100644 spec/fixtures/finders/users/wp_json_api/api_url/in_scope_subdir_ignored.html create mode 100644 spec/fixtures/finders/users/wp_json_api/api_url/out_of_scope.html diff --git a/app/finders/users/wp_json_api.rb b/app/finders/users/wp_json_api.rb index 91b0ea85..a795fc6e 100644 --- a/app/finders/users/wp_json_api.rb +++ b/app/finders/users/wp_json_api.rb @@ -53,7 +53,15 @@ module WPScan # @return [ String ] The URL of the API listing the Users def api_url - @api_url ||= target.url('wp-json/wp/v2/users/') + return @api_url if @api_url + + target.in_scope_urls(target.homepage_res, "//link[@rel='https://api.w.org/']/@href").each do |url, _tag| + uri = Addressable::URI.parse(url.strip) + + return @api_url = uri.join('wp/v2/users/').to_s if uri.path.include?('wp-json') + end + + @api_url = target.url('wp-json/wp/v2/users/') end end end diff --git a/spec/app/finders/users/wp_json_api_spec.rb b/spec/app/finders/users/wp_json_api_spec.rb index 6f7e2cb4..3d14c503 100644 --- a/spec/app/finders/users/wp_json_api_spec.rb +++ b/spec/app/finders/users/wp_json_api_spec.rb @@ -5,7 +5,10 @@ describe WPScan::Finders::Users::WpJsonApi do let(:fixtures) { FINDERS_FIXTURES.join('users', 'wp_json_api') } describe '#aggressive' do - before { allow(target).to receive(:sub_dir).and_return(false) } + before do + allow(target).to receive(:sub_dir).and_return(false) + allow(finder).to receive(:api_url).and_return(target.url('wp-json/wp/v2/users/')) + end context 'when only one page of results' do before do @@ -78,4 +81,54 @@ describe WPScan::Finders::Users::WpJsonApi do end end end + + describe '#api_url' do + let(:fixtures) { super().join('api_url') } + + context 'when url in the homepage' do + { + in_scope: 'https://wp.lab/wp-json/wp/v2/users/', + out_of_scope: 'http://wp.lab/wp-json/wp/v2/users/' + }.each do |fixture, expected| + it "returns #{expected} for #{fixture}.html" do + stub_request(:get, target.url).to_return(body: File.read(fixtures.join("#{fixture}.html"))) + + expect(finder.api_url).to eql expected + end + end + + context 'when subdir' do + before { allow(target).to receive(:subdir).and_return('cms') } + + { + in_scope_subdir: 'https://wp.lab/cms/wp-json/wp/v2/users/', + in_scope_subdir_ignored: 'https://wp.lab/wp-json/wp/v2/users/' + }.each do |fixture, expected| + it "returns #{expected} for #{fixture}.html" do + stub_request(:get, target.url).to_return(body: File.read(fixtures.join("#{fixture}.html"))) + + expect(finder.api_url).to eql expected + end + end + end + end + + context 'when not in the homepage' do + before { stub_request(:get, target.url) } + + its(:api_url) { should eql target.url('wp-json/wp/v2/users/') } + end + + context 'when api_url already found' do + before { allow(target).to receive(:sub_dir).and_return(false) } + + it 'does not check the homepage again' do + url = target.url('wp-json/wp/v2/users/') + + finder.instance_variable_set(:@api_url, url) + + expect(finder.api_url).to eql url + end + end + end end diff --git a/spec/fixtures/finders/users/wp_json_api/api_url/in_scope.html b/spec/fixtures/finders/users/wp_json_api/api_url/in_scope.html new file mode 100644 index 00000000..22c182e7 --- /dev/null +++ b/spec/fixtures/finders/users/wp_json_api/api_url/in_scope.html @@ -0,0 +1 @@ + diff --git a/spec/fixtures/finders/users/wp_json_api/api_url/in_scope_subdir.html b/spec/fixtures/finders/users/wp_json_api/api_url/in_scope_subdir.html new file mode 100644 index 00000000..71525fe0 --- /dev/null +++ b/spec/fixtures/finders/users/wp_json_api/api_url/in_scope_subdir.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/spec/fixtures/finders/users/wp_json_api/api_url/in_scope_subdir_ignored.html b/spec/fixtures/finders/users/wp_json_api/api_url/in_scope_subdir_ignored.html new file mode 100644 index 00000000..218372c8 --- /dev/null +++ b/spec/fixtures/finders/users/wp_json_api/api_url/in_scope_subdir_ignored.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/spec/fixtures/finders/users/wp_json_api/api_url/out_of_scope.html b/spec/fixtures/finders/users/wp_json_api/api_url/out_of_scope.html new file mode 100644 index 00000000..b793dc25 --- /dev/null +++ b/spec/fixtures/finders/users/wp_json_api/api_url/out_of_scope.html @@ -0,0 +1 @@ +