Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wpscanteam
GitHub Repository: wpscanteam/wpscan
Path: blob/master/app/finders/users/wp_json_api.rb
485 views
1
# frozen_string_literal: true
2
3
module WPScan
4
module Finders
5
module Users
6
# WP JSON API
7
#
8
# Since 4.7 - Need more investigation as it seems WP 4.7.1 reduces the exposure, see https://github.com/wpscanteam/wpscan/issues/1038)
9
# For the pagination, see https://github.com/wpscanteam/wpscan/issues/1285
10
#
11
class WpJsonApi < CMSScanner::Finders::Finder
12
MAX_PER_PAGE = 100 # See https://developer.wordpress.org/rest-api/using-the-rest-api/pagination/
13
14
# @param [ Hash ] opts
15
#
16
# @return [ Array<User> ]
17
def aggressive(_opts = {})
18
found = []
19
current_page = 0
20
21
loop do
22
current_page += 1
23
24
res = Browser.get(api_url, params: { per_page: MAX_PER_PAGE, page: current_page })
25
26
total_pages ||= res.headers['X-WP-TotalPages'].to_i
27
28
users_in_page = users_from_response(res)
29
found += users_in_page
30
31
break if current_page >= total_pages || users_in_page.empty?
32
end
33
34
found
35
rescue JSON::ParserError, TypeError
36
found
37
end
38
39
# @param [ Typhoeus::Response ] response
40
#
41
# @return [ Array<User> ] The users from the response
42
def users_from_response(response)
43
found = []
44
45
JSON.parse(response.body)&.each do |user|
46
found << Model::User.new(user['slug'],
47
id: user['id'],
48
found_by: found_by,
49
confidence: 100,
50
interesting_entries: [response.effective_url])
51
end
52
53
found
54
end
55
56
# @return [ String ] The URL of the API listing the Users
57
def api_url
58
return @api_url if @api_url
59
60
target.in_scope_uris(target.homepage_res, "//link[@rel='https://api.w.org/']/@href").each do |uri|
61
return @api_url = uri.join('wp/v2/users/').to_s if uri.path.include?('wp-json')
62
end
63
64
@api_url = target.url('wp-json/wp/v2/users/')
65
end
66
end
67
end
68
end
69
end
70
71