惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Stack Overflow Blog
Stack Overflow Blog
J
Java Code Geeks
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
博客园 - 【当耐特】
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Check Point Blog
月光博客
月光博客
腾讯CDC
Engineering at Meta
Engineering at Meta
博客园 - Franky
Vercel News
Vercel News
D
Docker
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
F
Fortinet All Blogs
Microsoft Security Blog
Microsoft Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
雷峰网
雷峰网
Google DeepMind News
Google DeepMind News
Martin Fowler
Martin Fowler
GbyAI
GbyAI
B
Blog
Hugging Face - Blog
Hugging Face - Blog
T
Tailwind CSS Blog

Hacker News

GitHub - SeanFDZ/macmind: Single-layer transformer in HyperTalk for the classic Macintosh Show HN: Agent-cache – Multi-tier LLM/tool/session caching for Valkey and Redis Bonsai 1-bit WebGPU - a Hugging Face Space by webml-community Moving a large-scale metrics pipeline from StatsD to OpenTelemetry / Prometheus GitHub - Nightmare-Eclipse/RedSun: The Red Sun vulnerability repository GitHub - SethPyle376/hiraeth: Local AWS emulator focused on fast integration testing, with SQS support, SQLite-backed state, and a debug-friendly web UI. GitHub - macOS26/Agent: Any AI, replaces Claude Code, Cursor, OpenClaw. Over 18 LLM providers (Claude, OpenAI, Gemini, Ollama, Zai, HF, Qwen) wired into a native Mac app that writes code, builds Xcode projects, bumps versions, manages git, automates Safari, use AppleScript, JS or Accessibility, extend Agent! w/ MCP Servers, run tasks from your iPhone via Messages. YouTube now lets you turn off Shorts I Made a Terminal Pager Burgers | マクドナルド公式 Commands — HackerNews CLI documentation ChatGPT for Excel PiCore - Raspberry Pi Port of Tiny Core Linux Live Nation illegally monopolized ticketing market, jury finds Google Broke Its Promise to Me. Now ICE Has My Data. Founding Engineer at Adaptional | Y Combinator CRISPR takes important step toward silencing Down syndrome’s extra chromosome GitHub - saffron-health/libretto: The AI toolkit for building reliable browser automations US v. Heppner (S.D.N.Y. 2026) no attorney-client privilege for AI chats [pdf] Retrofitting JIT Compilers into C Interpreters IPv6 – Google The Accursèd Alphabetical Clock Cybersecurity Looks Like Proof of Work Now Fragments: April 14 Cal.com Goes Closed Source: Why AI Security Is Forcing Our Decision | Cal.com - Scheduling Software for Online Bookings Laravel raised money and now injects ads directly into your agent When moving fast, talking is the first thing to break Too much Discussion of the XOR swap trick – Heather Cafe Introduction to Spherical Harmonics for Graphics Programmers The Grand Line
288,493 Requests in 24 Hours — How I Spotted an XML-RPC B...
2026-04-13 · via Hacker News

TL;DR

  • Cloudflare cache hit ratio on a WordPress site dropped to 0.8% — the real alarm, not CPU or uptime.
  • Root cause: a single Singapore DigitalOcean IP flooding /xmlrpc.php with 288,493 POSTs in 24 hours, using system.multicall to brute-force hundreds of credentials per request.
  • Fix: Cloudflare WAF rule blocking /xmlrpc.php at the edge, plus WP Multitool's Frontend Optimizer disabling xmlrpc inside WordPress — defense in depth, both layers on by default in 1.1.19.
  • Action for you: check your Cloudflare Top Paths weekly. If xmlrpc.php shows up in the top 3, you're already being hit.

Today I was glancing at Cloudflare analytics for one of my sites and something looked off. Cache hit ratio: 0.8%. That's not a typo. Zero point eight percent.

For a mostly-static WordPress site that should be sitting at 70–90%, 0.8% means something is very wrong. Either the cache rules are broken, or something is flooding the site with uncacheable traffic. Turned out to be the second one.

I pulled up the traffic breakdown and the answer was sitting right there. One IP from Singapore, 288,493 requests in 24 hours, all POSTs to /xmlrpc.php, all returning 200. That's about 12,000 requests per hour from a single DigitalOcean droplet. The site was still up because Cloudflare was absorbing most of it, but my origin was burning CPU on every single one of those requests.

Why 0.8% Cache Rate Was the Real Signal

Here's the thing about WordPress attacks on xmlrpc.php — they're almost invisible if you only watch uptime. The site loads fine for real visitors. The CPU graph might look a bit elevated. But the attack itself doesn't trigger any obvious alarm.

Cache rate is a great canary because xmlrpc.php is POST-only and marked dynamic. Every attack request counts against your cache rate denominator. When you see 288k uncacheable dynamic requests vs a few thousand normal cached ones, the ratio collapses.

So if your cache rate suddenly drops on an otherwise quiet WordPress site, don't immediately blame your plugins. Check what's being requested.

What system.multicall Actually Does

The vector is old but still works because so many sites leave xmlrpc enabled by default. Attackers POST XML payloads like this:

<?xml version='1.0'?>
<methodCall>
  <methodName>system.multicall</methodName>
  <params>
    <param><value><array><data>
      <value><struct>
        <member><name>methodName</name><value>wp.getUsersBlogs</value></member>
        <member><name>params</name><value><array><data>
          <value><string>admin</string></value>
          <value><string>password1</string></value>
        </data></array></value></member>
      </struct></value>
      ... [hundreds more credential pairs]
    </data></array></value></param>
  </params>
</methodCall>

One HTTP request, hundreds of login attempts. That's the amplification. A regular wp-login.php brute force triggers rate limiting and WAF rules after a few attempts. system.multicall lets you test 500 credentials in a single POST that looks like normal API traffic. That's why it's still the preferred vector in 2026 — efficient, quiet, and slips past naive rate limits that count requests instead of auth attempts.

How to Check If You're Being Hit

If you're on Cloudflare, the fastest way is the GraphQL analytics API. Query the top paths for the last 24 hours, grouped by path and cache status:

query($zone:String!, $since:Time!, $until:Time!) {
  viewer {
    zones(filter:{zoneTag:$zone}) {
      httpRequestsAdaptiveGroups(
        limit:20,
        filter:{datetime_geq:$since, datetime_leq:$until},
        orderBy:[count_DESC]
      ) {
        count
        dimensions { clientIP clientCountryName clientRequestPath cacheStatus }
      }
    }
  }
}

If /xmlrpc.php shows up in the top 3 paths with cacheStatus "dynamic" and a request count in the tens of thousands, you're being hit. Also check wp-login.php while you're there — where there's xmlrpc abuse there's usually a coordinated login flood from other IPs.

If you don't use the API, the Cloudflare dashboard has the same data under Analytics → Traffic. The Top Paths widget will give it away.

Fix #1 — Block It at the Edge

The fastest mitigation is a Cloudflare WAF custom rule. One line expression, block action:

(http.request.uri.path eq "/xmlrpc.php")

This stops the requests at Cloudflare's edge before they reach your origin. No CPU cost, no PHP execution, no bandwidth. After I deployed this rule the 288k/day flood stopped hitting my server entirely and the cache rate started recovering within the hour.

If you have dozens of zones to protect, the Cloudflare API makes this a one-liner per zone. I ran it on all my own zones in about 10 seconds.

Fix #2 — Disable It at the WordPress Level Too

Edge blocks are great but I'm a defense-in-depth person. If someone misconfigures the WAF or bypasses Cloudflare, I want WordPress itself to refuse xmlrpc requests.

You can do it with a few lines in functions.php:

add_filter('xmlrpc_enabled', '__return_false');
add_filter('xmlrpc_methods', function($methods) { return []; });

Or if you'd rather not touch code, any decent WordPress optimizer plugin has this option. My own plugin WP Multitool has it in the Frontend Optimizer module and it's on by default in the latest version — which is why I updated all my sites to 1.1.19 after spotting this attack. Install, activate, done — xmlrpc is disabled both ways.

The key insight: don't rely on a single layer. Edge WAF rules can be misconfigured, origin can be exposed directly, and plugins can be deactivated. Stack them so no single failure leaves you open.

Do You Actually Need xmlrpc in 2026?

Probably not. xmlrpc.php was the WordPress API before REST existed. These days:

  • The WordPress REST API handles everything xmlrpc used to do, better and with proper auth
  • Remote publishing apps have mostly moved to REST
  • Even WooCommerce and major page builders don't touch xmlrpc

The one remaining legit use case is the Jetpack mobile app, which still uses xmlrpc under the hood for some features. If you don't use Jetpack mobile, you can kill xmlrpc without losing anything. If you do, there are better ways — restrict xmlrpc to Jetpack's IP ranges via WAF rule instead of blocking outright.

In my case none of my sites need it, so I blocked it everywhere.

What I'd Do Going Forward

A few habits I'm adding after this:

Watch cache rate, not just uptime. A 5% drop in hit ratio on a static-ish site deserves a look. A 50% drop means something is happening right now.

Check top paths weekly. Five seconds in the Cloudflare dashboard, tells you immediately if an attack is warming up. Most brute force attempts start small and ramp up over days.

Block xmlrpc.php preemptively on new sites. It's one WAF rule. There's no reason to wait until you see 288k requests before adding it.

And if you're running WordPress anywhere without a CDN or WAF in front of it, fix that first. Cloudflare's free tier would have absorbed this entire attack without breaking a sweat.

The cache rate on my site is back to normal now. But I'm genuinely curious how many WordPress owners are getting hit right now and have no idea because they only check if the homepage loads.

If you run WordPress sites and want xmlrpc hardening (plus a bunch of other defense-in-depth optimizations) on by default, WP Multitool 1.1.19+ handles it automatically.