Engineering Case Study

When the Calendar Becomes the Attack Surface

The first attack hit on a holiday weekend. A nonprofit's site went from 2,000 visits a day to 400,000. By Monday morning, when someone finally noticed the trouble ticket, the damage was done. Hosting plan limits had been exceeded. The site had been intermittently down for two days.

The second attack hit on a Thursday afternoon. This time the client ran a large community events organization. Their biggest event of the year — a major outdoor festival drawing thousands of people — was scheduled for the following day. The site went completely down at 3pm. We got it back up at 3:46pm.

Both attacks followed the same pattern. Both targeted the same kind of site. Both exploited the same architectural vulnerability. And neither one was random.

What Was Being Attacked

Event calendar plugins — The Events Calendar, All-in-One Event Calendar, and others — generate a very large number of publicly accessible URLs. Every combination of date, category, tag, and view type produces a unique address. A single site with a year of events and community submissions might have hundreds of thousands of valid calendar URLs.

Bots don't need to be clever about this. They just enumerate. Request every date combination. Request every category. Request every tag. Request every view. The server has to respond to each one.

The problem is what happens on the server when it does. A calendar archive page isn't just serving static content. It's running a database query, generating schema output through an SEO plugin, rendering excerpts for every visible event, running theme filters. Stack those operations together and a single calendar archive request costs significantly more than the fraction of a cent it costs the attacker to send it.

An endpoint whose computational cost is much higher than the cost of requesting it is a bot attack waiting to happen.

That asymmetry is the vulnerability. It has nothing to do with outdated software or misconfiguration. It's structural. The calendar plugin was doing exactly what it was designed to do.

The Council

I run a multi-model AI council — persistent context windows across different models that develop specialization through use. Claude (Claude Sonnet) is my primary development partner. ChatGPT focuses on architecture and the Site Health plugin project we've been building together.

When the second attack happened, we were all in it together in real time. I was watching logs, Sabrina was in Cloudflare, and Claude and ChatGPT were working through what we were seeing.

The first thing ChatGPT did was slow me down.

I had identified a Google Cloud IP hitting wp-cron and admin-ajax repeatedly and was ready to block it. ChatGPT pushed back. The nonce reuse isn't suspicious on its own — Action Scheduler is designed to process queues over multiple requests. The WordPress user agent points toward a loopback, not an external attacker. The cadence is about once per minute, which is exactly what normal cron behavior looks like. Before blocking anything, ask: why is a loopback originating from that IP?

It turned out to be the hosting platform's cron infrastructure. If we had blocked it we would have broken legitimate background processing on the site we were trying to protect.

That exchange produced something worth keeping. Claude had initially flagged the IP as suspicious. ChatGPT corrected the analysis. Then ChatGPT articulated why:

Evidence before hypotheses. Separate what you observed from what you inferred. The question isn't "is this an attacker?" It's "why is this loopback originating from that IP?"

We ran the Action Scheduler queue check. Eleven pending jobs, healthy cadence, two minor migration hook failures from an old plugin update. Queue was fine. IP was legitimate. Calendar attack was the real incident.

That principle — evidence before hypotheses — shaped everything that came next. When we turned to the broader question of why these attacks were happening and how to defend against them systematically, we were applying the same discipline: separate what we observed from what we inferred, and make sure the abstraction we built matched the actual behavior, not the behavior we assumed.

The Economics

After the immediate crisis was resolved, the council kept working on the longer question: why were these attacks happening, and why were they timed the way they were?

The holiday weekend attack. The attack the day before the festival. A third site we later confirmed had been hit right before a major 4th of July event. The pattern wasn't random. These attacks were hitting event organizations at the exact moment their sites mattered most.

ChatGPT framed it in terms of attacker economics. An attacker has a budget — money, time, compute, attention. Their objective isn't to write the most elegant attack. It's to maximize return on effort. One-off attacks don't scale. The sweet spot is something reusable, slightly adaptable, and cheap to retarget.

AI reduces the cost of discovering targets, understanding their structure, and writing tooling. It doesn't eliminate the cost of operating at scale. And once an attack reaches your server, it has to express itself as requests. Those requests have observable properties — concurrency, traversal strategy, endpoint selection, cache behavior — that are much harder to hide than the code that generated them.

Whether the attack code was handwritten, generated by an LLM, or copied from GitHub, once it reaches your server it has to behave. Behavior is what we can detect.

The defender's version of that economic argument: if every new attack requires a new mitigation written from scratch, you're losing. The goal is defenses that are more reusable than the attacks. Which means the abstraction has to be right.

The wrong abstraction: protect /calendar/summary/. That's one URL pattern from one attack on one plugin.

The right abstraction: protect expensive public behaviors. Any endpoint where the computational cost to serve it is significantly higher than the cost to request it is a potential attack surface. That covers calendar archives today. It covers whatever comes next.

What We Built

Zee Calendar Defender is a WordPress plugin that monitors calendar archive request rates and responds automatically before a bot attack can take down the whole site. It targets The Events Calendar and All-in-One Event Calendar — the two confirmed attack vectors we'd seen.

The detection uses a transient-based rolling counter. One database read per calendar request, counter written in batches to minimize load. The detection mechanism had to be cheap — it runs on every calendar archive request, and the last thing you want is detection that compounds the load during an attack.

The response is tiered:

Tier 1 fires when the counter hits the first threshold. Email alert sent. No visitor impact. Just watching more closely.

Tier 2 fires at the second threshold. Calendar archive pages — the browsing and filtering pages bots enumerate — return a clean maintenance message. Individual event pages remain fully accessible. A visitor searching for a specific festival or event can still find it. Zee Creative gets an urgent alert that includes a ready-to-paste Cloudflare WAF rule.

Tier 3 fires when the attack is severe enough that the whole site is at risk. Full calendar lockdown. Detection stops running — reading one option flag is cheaper than running the counter during a critical load situation. Homepage and all other pages stay up.

The design argument for tiered automated response rather than human-in-the-loop only: by the time a human sees an alert on a holiday weekend, the site may have been down for 48 hours. Calendar down is better than site down. Individual event pages staying accessible during Tier 2 means the most important content survives the worst of the attack while we work on the network-level fix.

The system should reduce the defender's marginal cost faster than attackers can reduce theirs. Every incident should make the defenses broadly stronger.

The plugin is deployed on client sites running calendar plugins. It's been tested on a low-traffic site with off-season events to calibrate thresholds without affecting real visitors. The Cloudflare WAF rule that was hand-applied during the festival attack is now generated automatically and included in every Tier 2 alert email.

What Came Out of It

The incidents, the council analysis, and the plugin are all going into the Site Health plugin project — a broader operational monitoring tool I've been building with ChatGPT. Expensive plugin combination detection. Action Scheduler queue health. Traffic anomaly flagging. Operational Risk as a distinct category separate from security and performance.

The thread that connects all of it is the same principle the Oracle campus isolation problem pointed toward: when the tool assumes one thing and reality is another, the fix belongs at the architecture level. Policy won't hold. Detection won't help if it fires after the damage is done. The right level to solve the problem is the level where the structural mismatch actually lives.

In this case: the calendar plugin assumes cooperative traffic. Reality contains adversarial traffic. The fix is a layer that intercepts between the request and the expensive operation, before the server is already underwater.

The council got there by arguing about a Google Cloud IP at 3pm on a Thursday before a summer festival. I'll take it.

Back to Engineering Case Studies