> ## Documentation Index
> Fetch the complete documentation index at: https://docs.37audits.com/llms.txt
> Use this file to discover all available pages before exploring further.

# XML-RPC Auditor

> Finds XML-RPC methods attackers use for password guessing and DDoS on WordPress and Liferay

> [!NOTE]
>
> **Security Auditor**: checks whether the site's XML-RPC endpoint answers anyone, and whether it offers `system.multicall` (password guessing in bulk) or `pingback.ping` (the site fetches any URL a stranger gives it).

> **Protection**
>
> Finds the old remote API that bots hammer for admin passwords and abuse to attack other sites.

> **Read-only**
>
> Lists methods or sends a call the platform rejects before running it. It never logs in and never sends a pingback.

XML-RPC is an old remote API. WordPress serves it at `xmlrpc.php` and turns it on by default. Liferay serves it at `/xmlrpc/*`, where Blogs registers pingbacks. Few sites use it today: the WordPress block editor, the REST API and the mobile apps use `/wp-json`. Attackers still use it every day:

* **`system.multicall`** bundles many calls into one request. A bot can try hundreds of passwords per HTTP request and get past login rate limits that count requests.
* **`pingback.ping`** makes the site fetch a URL the caller chooses. Attackers send it to thousands of sites at once to flood a victim (DDoS reflection), or point it at internal addresses (SSRF).

## How it works

1. **Fetch**: requests the audited URL with `GET` as 37AuditsBot. A blocked request ends the audit with `590`. Any other failure (timeout, DNS, TLS, non-2xx answer) ends it with `500`.
2. **Platform**: picks the first platform named in the project's software stack. Otherwise it picks the first one the page reveals:
   * **WordPress**: the `generator` meta tag, the REST API `Link: <…>; rel="https://api.w.org/"` header, an `X-Pingback` header, or `/wp-content/` / `/wp-includes/` assets.
   * **Liferay**: the `Liferay-Portal` header, or the `Liferay.ThemeDisplay` / `Liferay.authToken` globals.
   * **Neither**: it still probes WordPress's `xmlrpc.php`, so a WordPress site that hides its generator is caught. If that endpoint does not answer XML-RPC, the result is `INFORMATION` (`100`) and the run is not charged.
3. **Probe**: sends one `POST` (`content-type: text/xml`):
   * **WordPress**: `system.listMethods` to the `X-Pingback` URL when the page advertises one, otherwise to `xmlrpc.php` next to the REST API root. WordPress answers with every method it offers.
   * **Liferay**: `pingback.ping` **without parameters** to `/xmlrpc/pingback`. Liferay's `XmlRpcServlet` looks the method up before checking the arguments. A registered method answers fault `-32602` ("Method arguments are invalid") and an unknown one `-32601` ("Requested method not found"). The method never runs.
   * Any HTTP answer (403, 404, 500…) counts as XML-RPC being off.
   * **Second round**: if the endpoint of a recognised platform cannot be reached at all (connection reset, refused, timeout), the auditor fetches the site root. When the root answers `2xx`, it sends the probe once more. A second failure means a firewall drops XML-RPC on purpose: `SUCCESS` (`201`). An answer on the second try is evaluated as usual. If the root fails too, the site itself is down and the result is `ERROR` (`501`).
4. **Jetpack**: when a WordPress endpoint answers, the auditor looks for Jetpack, which needs XML-RPC to talk to WordPress.com. Jetpack adds nothing to the method list a stranger sees, so the signals are its assets (`/wp-content/plugins/jetpack/`) on the page or its `jetpack/v4` namespace in the REST API index (one `GET`). With Jetpack, the recommendations say to allow `xmlrpc.php` only from [Jetpack's IP ranges](https://jetpack.com/ips-v4.txt) instead of disabling it. The verdicts do not change: the auditor is not a Jetpack server, so an answer means the endpoint is open to everyone.
5. **Rules**: `system.multicall` listed (`400`) and `pingback.ping` listed (`401`) fail. A WordPress endpoint that answers XML-RPC at all warns (`300`). A Liferay endpoint with `pingback.ping` registered warns (`301`).
6. **Aggregate**: FAIL wins over WARNING. When every rule passes, the audit is `SUCCESS` (`200`).

## What it audits

Every row maps to one `checkRule*` method and one `CheckCode`, in the order the auditor runs them. CheckCode suffixes use status ranges: `100` information, `200` success, `300–399` warning, `400–499` fail, `500–599` error.

| CheckCode | Status | When it fires | Recommendation | Why it matters |
| - | - | - | - | - |
| `37A-XmlRpcAuditor-100` | `INFORMATION` | Neither the stack nor the page names WordPress or Liferay, and `xmlrpc.php` does not answer XML-RPC. Not charged. | If `{host}` runs WordPress, Liferay, add it to the project's software stack so its XML-RPC endpoint is checked. | — |
| `37A-XmlRpcAuditor-400` | `FAIL` | The endpoint lists `system.multicall`. | Disable XML-RPC on `{host}` (block "`{endpoint}`" at the web server or with a security plugin). The xmlrpc\_methods filter cannot remove system.multicall, so if a publishing app needs XML-RPC, allow the endpoint only from that app's addresses. With Jetpack: allow "`{endpoint}`" only from Jetpack's IP ranges ([https://jetpack.com/ips-v4.txt](https://jetpack.com/ips-v4.txt)). | Attackers use it to try hundreds of passwords in a single request, slipping past login limits and putting admin accounts at risk of takeover. |
| `37A-XmlRpcAuditor-401` | `FAIL` | The endpoint lists `pingback.ping`. | Turn off pingbacks on `{host}` (Settings → Discussion, and on existing posts), and remove pingback.ping with the xmlrpc\_methods filter or disable XML-RPC at "`{endpoint}`". With Jetpack: remove pingback.ping (Jetpack does not need it), or allow the endpoint only from Jetpack's IP ranges. | Attackers can make the site send requests to other servers, using it in DDoS attacks or to reach internal systems, which can get the server blocklisted. |
| `37A-XmlRpcAuditor-300` | `WARNING` | The WordPress endpoint answers XML-RPC requests: a method list, a fault, or "XML-RPC server accepts POST requests only". | Disable XML-RPC on `{host}` (block "`{endpoint}`" at the web server or with a security plugin) unless a remote publishing app needs it. With Jetpack: keep XML-RPC but allow "`{endpoint}`" only from Jetpack's IP ranges ([https://jetpack.com/ips-v4.txt](https://jetpack.com/ips-v4.txt)). | Every XML-RPC method is another door into the site that most WordPress sites never use, so leaving it open adds risk with no benefit. |
| `37A-XmlRpcAuditor-301` | `WARNING` | Liferay's `/xmlrpc/pingback` answers an empty `pingback.ping` call with fault `-32602`: the method is registered. | Set blogs.pingback.enabled=false and message.boards.pingback.enabled=false in portal-ext.properties (or LIFERAY\_BLOGS\_PERIOD\_PINGBACK\_PERIOD\_ENABLED=false), or block /xmlrpc/\* at the proxy in front of `{host}`. | Pingbacks let anyone make the server fetch outside URLs, so attackers can use it to send traffic at other sites, and few Liferay sites use pingbacks at all. |
| `37A-XmlRpcAuditor-201` | `SUCCESS` | The endpoint dropped the probe twice (reset, refused or timed out) while the site root answered `2xx` in between: a firewall blocks XML-RPC. | — | — |
| `37A-XmlRpcAuditor-200` | `SUCCESS` | All rules passed. Message names the endpoint and its HTTP answer. | — | — |
| `37A-XmlRpcAuditor-500` | `ERROR` | The audited page could not be fetched (timeout, DNS, TLS, or a non-2xx answer other than a block). | Make sure "`{url}`" is reachable by the auditor so its XML-RPC endpoint can be checked. | — |
| `37A-XmlRpcAuditor-501` | `ERROR` | The XML-RPC endpoint of a recognised platform could not be reached (network error or timeout), and the site root failed too, so a firewall block cannot be told apart from an outage. | Make sure "`{endpoint}`" answers the auditor (any HTTP status) so XML-RPC can be checked. | — |
| `37A-XmlRpcAuditor-590` | `ERROR` | The audited page answered HTTP 403, HTTP 429 or a Cloudflare challenge, so 37AuditsBot was blocked before it could read the page. | Allow 37AuditsBot in your firewall or bot protection: allowlist its user agent, or verify its Web Bot Auth signature. See [https://www.37audits.com/bot](https://www.37audits.com/bot). | While 37AuditsBot is blocked this audit cannot look at the site, so problems on it go unreported. |

## Output documentation

| Status | Description | Test logic |
| - | - | - |
| **SUCCESS** | XML-RPC is off or offers nothing risky | The endpoint does not answer XML-RPC (403, 404, HTML page…), or lists no risky method (`200`); a firewall drops the probe twice while the site answers (`201`). |
| **WARNING** | XML-RPC is reachable | WordPress endpoint answers (`300`); Liferay has `pingback.ping` registered (`301`). |
| **FAIL** | Attackers can abuse XML-RPC today | `system.multicall` listed (`400`); `pingback.ping` listed (`401`). |
| **ERROR** | The auditor could not check | Audited page not fetched (`500`); endpoint unreachable (`501`); site blocked 37AuditsBot (`590`). |
| **INFORMATION** | Nothing to audit | No WordPress or Liferay and no XML-RPC at `xmlrpc.php` (`100`); not charged. |

## Risks and considerations

### Who still needs XML-RPC

* **Jetpack** and some older remote publishing apps still use XML-RPC on WordPress. If you depend on them, keep the endpoint but allow it only from Jetpack's IP ranges (or the app's addresses), and remove `pingback.ping` with the `xmlrpc_methods` filter. That filter cannot remove `system.multicall`: WordPress adds the `system.*` methods after it runs.
* The WordPress block editor, the REST API and the current mobile apps do not need it.

### How to turn it off

* **Web server**: deny `xmlrpc.php` (Apache `<Files xmlrpc.php> Require all denied </Files>`, nginx `location = /xmlrpc.php { deny all; }`). This is the most complete fix.
* **Plugin**: most security plugins (Wordfence, Solid Security, "Disable XML-RPC") can block it.
* **Liferay**: set `blogs.pingback.enabled=false` and `message.boards.pingback.enabled=false`, or block `/xmlrpc/*` at the proxy or web server in front of the portal.

### Limits of this check

* A WordPress plugin can block XML-RPC logins while `system.listMethods` still lists every method. The auditor reports what is listed. It does not try a login to find out.
* On Liferay, the auditor sees that `pingback.ping` is registered, but it cannot read `blogs.pingback.enabled` without running the method. That is why the finding stays a `WARNING` even after pingbacks were turned off in the configuration. Blocking `/xmlrpc/*` clears it.
* Some firewalls (fail2ban, WAF rules) ban the caller's IP for a while after an XML-RPC request. During that ban, other audits of the same host can fail to fetch the page.
* Only the endpoint of the audited site is probed. Other WordPress installations on the same host (in another subdirectory) need their own monitored URL.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.