For two weeks, anyone who typed one customer’s short address got an error page instead of their homepage. The customer never saw it, and nobody reported it, because the other ways into their site worked fine the whole time.

We found it by trying to break our own work. Nobody had complained.

The rule that worked

A few weeks earlier we had been closing out a run of scanner traffic hammering the platform’s edge. Vulnerability scanners probe the same short list of paths on every site they touch: WordPress admin routes, a handful of framework debug endpoints, and a scattering of generic strings that only ever show up in recon tooling. The fix was a blocklist rule that matched those exact strings and dropped the request before it reached the origin server. It worked. Failed requests reaching the origin dropped hard, and we moved on to the next scanner in the queue.

One of the strings we added was a short, unremarkable path segment. Across a week of logs, on every site the platform hosts, it had shown up zero times as a legitimate 200 response. That was the bar we had set for adding anything to the rule, and zero looked like proof it was safe.

It was proof of something else. The platform gives every customer a canonical short URL built straight from their own username: one path segment, nothing else. The string we had blocked as a probe signature was also, by coincidence, one customer’s actual username. Their front door, the address printed on a flyer or pasted into an email, matched the rule and got dropped at the edge.

Why it stayed hidden

Other routes to that customer’s site kept working. Only the short address failed, and every uptime signal we had only ever exercised the working routes. The account looked healthy from every angle we were checking.

The pass built to disprove it

What surfaced it was a habit rather than a monitor. After shipping a rule like this, we run a pass designed to disprove it instead of confirm it. We went looking for the failure we would have argued against if asked directly: could any string on that blocklist also be a real username? We checked the full list against the actual customer table instead of trusting that “obviously a scanner path” meant anything. It took one query to find the collision.

We removed the clause instead of narrowing it. A scanner probe path is a nuisance. A paying customer’s homepage returning an error is a failure we will not accept as a tradeoff, so the obscure signature lost and the customer’s address won. We then checked every other value still on that rule against the customer table, close to thirty entries, and found no other collisions. That told us this was a one-off coincidence and not a pattern to redesign around.

The summary that skipped clauses

There was a second bug in there that we did not expect. The tool we had been using to summarize what was on that rule understood only one kind of match clause and skipped the others without any warning. The count it reported had been wrong for a while, and it made the rule look shorter and easier to review than it was. That is part of why the collision sat unnoticed: the tooling we trusted to tell us what the rule contained was not telling us the whole rule. We fixed it in the same sitting, since a summary tool that drops entries silently is worse than having none.

What the check actually answered

An exact-match rule on a short string is only as safe as the space of real values it might also equal. “We checked it wasn’t getting legitimate 200s” answers a different question than “we checked it wasn’t someone’s actual address.” The two look like the same check. The gap between them is where a real customer sat, locked out of their own short address, for two weeks.

So before a block rule goes live, we now check every string on it against the customer table as well as against past traffic. We also confirm that the summary we review shows every clause on the rule, and we run a pass built to disprove the rule after it ships. A customer can be locked out of their own address while every uptime signal stays green.