搜索全站
安全防护 12 分钟阅读

WordPress XML-RPC 是什么:要不要关闭与安全风险处理

xmlrpc.php 是 WordPress 被爆破和 DDoS 放大的经典入口,但直接删文件会破坏官方 App 和部分插件。本文讲清 XML-RPC 的真实用途、三类攻击原理、四种处理方式(彻底关闭/部分禁用/限速/白名单)的取舍与配置代码。

U
UFO_PF 2023-06-03 · 阅读 12 分钟
Wo 安全防护
阅读提示
本文约 4,663 字,预计阅读 12 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:日志里几千条 xmlrpc.php 请求

看服务器访问日志,经常能发现大量这样的请求:

185.220.101.x - - [10/Oct/2026:03:12:44] "POST /xmlrpc.php HTTP/1.1" 200
185.220.101.x - - [10/Oct/2026:03:12:45] "POST /xmlrpc.php HTTP/1.1" 200
... 连续几千条

这些几乎全是攻击:system.multicall 暴力破解(一个请求里塞几百次登录尝试,绕过登录失败限速)和 pingback 反射 DDoS(把你的站点当放大器去打别人)。

但 XML-RPC 同时也是 WordPress 官方手机 App、桌面客户端、部分第三方发布工具依赖的协议。一刀切删掉,可能把正常功能一起干掉。所以先要弄清楚它在你站上有没有被用到。

原理分析:XML-RPC 是什么,还剩什么用

XML-RPC 是老牌的远程调用协议(XML over HTTP POST),比 REST 早十几年。WordPress 早期就内置 xmlrpc.php,用于:

  1. 远程发布:博客客户端(Windows Live Writer、MarsEdit、WordPress 官方 App);
  2. Pingback / Trackback:站与站之间的引用通知;
  3. Jetpack 的部分功能(老功能仍有依赖);
  4. 部分插件的跨站通信。

请求体长这样:

<?xml version="1.0"?>
<methodCall>
  <methodName>wp.getPosts</methodName>
  <params>
    <param><value><i4>1</i4></value></param>
    <param><value><string>username</string></value></param>
    <param><value><string>password</string></value></param>
  </params>
</methodCall>

三类真实攻击:

攻击 1:system.multicall 爆破

XML-RPC 有个方法叫 system.multicall,允许在一个 HTTP 请求里调用多次方法。攻击者把它和 wp.getCategories(需要账号密码)组合,一个请求尝试几百组密码,完全绕过了登录页的失败次数限制。这是 WordPress 站点被撞库成功率最高的方式。

攻击 2:pingback 反射放大

pingback.ping 方法允许 A 站告诉 B 站”我引用了你”,B 站会去 A 站抓页面验证。攻击者伪造大量 pingback 请求,源 IP 填受害者,于是成百上千个 WordPress 站点同时去请求受害者——分布式放大 DDoS。

攻击 3:用户信息枚举

wp.getUsersBlogs 等方法在旧版本可以探测用户名。

怎么判断你的站有没有在用 XML-RPC

看访问日志里有没有合法的 xmlrpc 请求:

grep "xmlrpc.php" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head

如果全是可疑 IP(境外、短时间大量),说明没人用,可以关。如果看到自己公司的固定 IP 或 App 的请求,就要留。

保姆级实操

方案一:彻底关闭(最常用、推荐)

代码方式(子主题 functions.php):

// 完全禁用 XML-RPC
add_filter( 'xmlrpc_enabled', '__return_false' );

这个过滤器会让 xmlrpc.php 返回 405 并提示 “XML-RPC services are disabled on this site.”。

Nginx 层直接挡(性能最好,不进 PHP):

location = /xmlrpc.php {
    deny all;
    access_log off;
    log_not_found off;
}

Apache(.htaccess):

<Files xmlrpc.php>
    Require all denied
</Files>

宝塔面板:网站 → 设置 → 配置文件,在 server 块里加上面的 Nginx 规则。

方案二:只关危险方法,保留发布功能

如果确实用 App 或第三方工具发布,只禁用 system.multicall 和 pingback:

// 禁用 pingback
add_filter( 'xmlrpc_methods', function( $methods ) {
    unset( $methods['pingback.ping'] );
    unset( $methods['pingback.extensions.getPingbacks'] );
    unset( $methods['system.multicall'] );
    return $methods;
});

方案三:只关 pingback(保留远程发布)

后台路径:设置 → 讨论 → 取消”允许其他博客发送链接通知(pingback)”。或者:

add_filter( 'xmlrpc_methods', function( $methods ) {
    unset( $methods['pingback.ping'] );
    return $methods;
});

// 同时去掉 HTTP 头里的 X-Pingback
add_filter( 'wp_headers', function( $headers ) {
    unset( $headers['X-Pingback'] );
    return $headers;
});

方案四:限速(CDN / Nginx)

Cloudflare WAF 建规则:

(http.request.uri.path eq "/xmlrpc.php") → 托管挑战 / 阻断

或者用速率限制规则:同一 IP 每分钟超过 5 次 POST /xmlrpc.php → 阻断 1 小时。

Nginx 限速:

limit_req_zone $binary_remote_addr zone=xrpc:10m rate=6r/m;

location = /xmlrpc.php {
    limit_req zone=xrpc burst=2 nodelay;
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}

方案五:IP 白名单

只有自己公司 IP 能用:

location = /xmlrpc.php {
    allow 203.0.113.10;
    deny all;
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}

验证是否关闭成功

curl -X POST https://example.com/xmlrpc.php \
  -H "Content-Type: text/xml" \
  -d '<methodCall><methodName>system.listMethods</methodName></methodCall>'
  • 彻底关闭:返回 403(Nginx 挡)或 405 + “XML-RPC services are disabled”
  • 只关部分方法:返回的方法列表里没有 pingback.ping / system.multicall

顺手清理已有的 pingback 垃圾

后台文章里的 pingback 评论会堆积:

SELECT COUNT(*) FROM wp_comments WHERE comment_type = 'pingback';

DELETE FROM wp_comments WHERE comment_type = 'pingback';
DELETE FROM wp_comments WHERE comment_type = 'trackback';

常见踩坑与失败案例

  1. 案例一:某站长直接把 xmlrpc.php 文件删了。WordPress 升级后文件又被写回来,之前的防护失效,而他不知道。应该用配置规则挡,而不是删文件。
  2. 案例二:关了 XML-RPC 之后,客户的 WordPress 手机 App 发不了文章,投诉到建站方。正确做法是先查日志确认有没有合法请求,有就走”方案二/三”只关危险方法。
  3. Jetpack 报错:Jetpack 的部分功能依赖 xmlrpc,关闭后后台提示连接失败。如果不用 Jetpack 无所谓,用了就只关 pingback 和 multicall。
  4. 关了还被打:如果是在 WordPress 层(xmlrpc_enabled)关的,请求仍会进 PHP,消耗资源。高并发攻击时要在 Nginx 层挡,或者在 CDN 层挡(根本不打到源站)。
  5. deny all 忘了保留 fastcgi 配置:某些复制的规则导致所有 PHP 请求都被挡。Nginx 的 location = /xmlrpc.php 只匹配这一个文件,别忘了其他 location 正常配置。
  6. 案例三:某站在 .htaccess 里加了规则,但服务器是 Nginx,规则完全不生效,防护是假的。确认服务器类型再写规则。
  7. trackback 和 pingback 要一起关:很多人只关了 pingback,trackback 垃圾照收。

总结

XML-RPC 是遗留协议,现在的合法用途只剩”第三方客户端远程发布”。处理策略:九成站点直接彻底关闭(Nginx 层的 location = /xmlrpc.php { deny all; } 最省资源);确实用 App 发布的,只 unset 掉 system.multicall 和 pingback.ping;高并发攻击要在 CDN 层挡。判断依据是访问日志里有没有合法来源的请求。两个必须记住的点:不要靠删文件来关闭(升级会恢复),关闭前先确认服务器类型(Nginx 还是 Apache,写错规则等于没防护)。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。