xmlrpc.php, User Lists, Author Archives, and wp-cron https://vulnify.app/blog/wordpress-xmlrpc-user-enumeration-and-wpcron A public WordPress endpoint is not automatically a vulnerability. Judge xmlrpc.php, the users route, author archives, and wp-cron separately, and do not disable a route your site still needs. WordPress publishes several URLs that worry people the first time a scan names them. xmlrpc.php , the REST users collection, author archives, and wp-cron.php are not the same finding. Public availability is not, by itself, a vulnerability. Blanket disabling can also break Jetpack, a mobile publisher, an author page you meant to keep, or a cron trigger your host still calls. Judge each endpoint on its own. The longer scanning guide names these routes and then moves on. This article is the follow-up: what a response means, and what to change. Start with non-intrusive WordPress vulnerability scanning if you still need the boundary of a public check. Plugin advisories belong in the public scan linked above, not here. xmlrpc.php is usually worth closing xmlrpc.php is an old remote-procedure interface. Some sites still need it for a specific integration. Many do not. When it answers on the public site, Vulnify’s comprehensive WordPress checks can record the HTTP status and, when the endpoint speaks XML-RPC, request a read-only method list. That list is not an attack. Pingback and multicall are not called. The finding means the interface is there and advertised methods that are often abused, such as multicall, which lets a client batch work. If nothing in your stack still requires XML-RPC, turn it off or return 403 for that file at the web server. If one integration needs it, allow only that integration’s source instead of the whole internet. Recheck after the change. A method list that disappears is the result you want. Do not confuse this with a plugin CVE. The file can be a stock WordPress file and still be more surface than you need. A public users route is exposure, then a decision The REST route that lists users can reveal usernames. Usernames are not passwords, and they are useful to anyone guessing passwords. Some sites want author names public. Some do not. Read the response before you block the API. A 401 or an empty collection is a different result from a JSON list of administrator slugs. If the list is intentional, say so in the ticket and keep the author pages consistent with it. If it is not, remove the public listing with a small plugin or a filter your developer owns, and confirm a second request no longer returns the accounts. Blocking all of wp-json because one route listed users will break the block editor and a number of plugins. Narrow the change to the users collection. Author archives leak the same names a different way WordPress author archives and the ?author=1 style of URL can redirect to an author slug. Scanners request a few low author IDs because those redirects reveal the login name of early users, often the first administrator. That is enumeration, not proof that the password is weak. You have two honest options. Keep the archives because the site is a magazine and the names are bylined, and treat the scan note as accepted exposure. Or stop publishing author archives and stop redirecting numeric author IDs, then confirm the IDs no longer disclose a slug. Hiding the login form while leaving the author slug on every post does not undo the disclosure. Pair this with the login advice in WordPress security hardening , especially anything that still accepts the revealed username plus a password. wp-cron.php is a trigger, not a backdoor wp-cron.php is how WordPress runs scheduled work on many hosts: a visitor, or a request, causes due tasks to run. Seeing it on the public site is normal. It becomes a problem when anyone can hammer it, when it exposes errors, or when a compromised plugin has registered a task you did not intend. A scan that notes the URL is asking you to decide whether that trigger should stay public. Busy sites often disable the visitor-triggered runner and call cron from the host on a schedule instead. That is a performance and abuse decision. It does not, by itself, mean the site was hacked. Open the scheduled events list in wp-admin when you are already investigating a bad plugin. Unexpected tasks matter more than the existence of the cron file. For a backdoored plugin, follow how to check site compromise signals , and look at scheduled tasks there. What the comprehensive check is actually doing On a comprehensive WordPress pass, public reads can include wp-json , the users endpoint, a handful of author IDs, xmlrpc.php , the login URL, cron, the feed, and maintenance files. The XML-RPC method list runs only when the endpoint answers, and it is read-only. None of that logs into wp-admin. None of it proves a password works. A finding is an observation about a URL, plus the guidance for that URL. Run the check from the WordPress stack checker against the canonical public site, not against a random post. After you change a server rule, run it again. A cached 200 from a CDN is a failed change even when the origin now returns 403. Write the four conclusions separately A sensible ticket often looks like this. XML-RPC: disabled, because no integration needs it. Users route: blocked from anonymous reads, because author names are not a product feature. Author archives: kept, because the blog bylines them, and the risk is accepted. Cron: left public, because the host does not offer a system cron, and the task list was reviewed. Four lines. Four owners. One scan. If you disable all four because the report used serious words, you will break something you needed and you will still have the plugin-vulnerability work undone. Endpoints and CVEs are different queues. Retest the URL, not the feeling After a server rule change, request the same URL the finding named. A 403 from the origin and a 200 from the CDN means the rule is not in front of visitors yet. Purge that URL and request it again from a network that is not your office cache. Record the status code in the ticket next to the date. Saying XML-RPC is disabled, without a status code, is how the file is still answering next quarter. Do the same for the users collection and for an author id. You are looking for the disclosure to stop, or for a written acceptance that the names stay public. wp-cron can keep returning 200. That is fine when you decided the trigger stays. The retest proves you looked. It does not need to end in a block. From finding to verified fix is the same close-out, applied to a route instead of a patch. Frequently asked questions Does a listed XML-RPC method mean the scan attacked the site? No. Comprehensive mode can request the method list. It does not call pingback or multicall. The finding is that those names were advertised. Is wp-json itself a vulnerability? No. The REST API is part of WordPress. A specific route that lists users, or a plugin route with a flaw, is the thing to judge. Do not block the whole API to silence one collection. Should every site turn off xmlrpc.php? Turn it off when you cannot name the integration that still posts through it. Keep it, restricted to that integration, when you can name one. Recheck the URL after the rule is deployed.