Invasion Investigation · Part 9
The files came off in an afternoon. This didn’t.
By now the malicious files are gone and the door is closed. And there are still thousands of pages under your domain name in Google’s records.
That’s not a failure of your cleanup. The index damage is a separate problem with a separate lifespan, and understanding why is the difference between fixing it and accidentally making it permanent.
What was actually published under your name
Not gibberish, and not random. A working storefront, cloned.
From the case file. The pages served on this domain were a Japanese home-improvement retailer’s product catalogue, rebuilt wholesale, with photography pulled from Japanese resale marketplaces.
Every page carried structured data marking the item new and in stock, with star ratings between 4.3 and 4.9 and review counts from 816 to over 9,000.
None of it was real — and the Japanese titles frequently said the opposite of the markup. Used. Like new. Reserved for a specific buyer. One said transaction ended. One listing was a second-hand car with a manual gearbox, sold as new stock with a delivery estimate.
The contradiction tells you the purpose. Nobody was fulfilling orders. The pages existed to rank, carry advertising and analytics tags, and move traffic somewhere else.
From the case file. Those pages carried live tag manager containers, an analytics property, an advertising conversion tag, a retargeting tag and a session-recording key — all firing from a domain whose owner had no idea.
And Search Console had validated the Product, Merchant listing and Review markup. The structured data was well-formed, so it passed. Google was serving rich results — stars, prices, availability — for products that didn’t exist, from a business that had never sold them.
Why your domain
Because it isn’t aimed at your customers. It’s aimed at a different search market entirely, and your domain is being borrowed for its reputation.
An established domain with years of clean history gets new pages indexed far faster than a throwaway one. That’s the whole asset. Twenty years of trust, rented out without asking.
Which is also why the language rarely matches the site, and why it’s almost never something you’d notice from your own homepage.
How twenty pages became eight thousand
This is the mechanism worth understanding, because it explains the scale.
The pages were built to breed.
From the case file. Each spam page carried roughly 240 links to other spam URLs — and the link sets barely overlapped. Across twenty captured pages there were 4,797 distinct URLs with only one repeat.
Crawl one page, inherit 240 more. Crawl those, inherit 240 each. Twenty seed pages was enough to generate the entire first wave.
And you could never have seen it. Those links existed in the version served to crawlers. View the source of a spam URL in your own browser and you get the third branch — your real site, or a not-found page. The mesh was only ever in somebody else’s copy.
That’s why Part 2 sends you to Search Console’s stored crawl rather than your browser. It’s the only place the page you’re actually trying to look at exists.
And they closed off the obvious defence:
From the case file. Every spam page declared itself canonical to its own URL — the tag that normally says “this content really lives over there” was pointed at itself. So Google had nothing to consolidate them into. Each of the thousands was, by its own declaration, a unique page.
And the discovery method was chosen per site
This is the detail that shows it wasn’t automated blindly.
From the case file. Two domains in the same account got two different tactics, matched to their profiles.
The twenty-year-old domain, crawled daily, got the link mesh — it was already being visited, so it only needed something to find.
The static brochure site nobody crawled got a
robots.txtdeclaring twenty sitemaps, because a site nobody visits needs an invitation. Rewrite rules routed every sitemap request to a generator that produced them on demand.
Same operator, same week, opposite approaches. Somebody looked at each domain and decided.
Why you never saw any of it
Because you weren’t shown it. The routing was three-way.
From the case file. The logic checked every request:
A crawler — anything whose user agent contained
googlebot,yahoooraol— was served spam fetched live from the operator’s own server.A human arriving from a search engine with a Japanese language preference was redirected to whatever was being monetised that day.
Everyone else — including the owner, every time — fell through to the real WordPress site.
Sixteen months of being served your own website, on purpose.
There’s a practical consequence worth carrying: clicking a spam URL and getting “page not found” proves nothing. You’re in the third branch. Use Search Console’s URL inspection and read what Googlebot was actually given.
And it explains why the files were never the problem. Nothing was stored. The handler fetched content from elsewhere on every request, so there was no spam on your server to find — just a small, unremarkable script and a rewrite rule. Delete ninety-nine per cent of what they left and the operation runs at a hundred per cent, as long as one handler and one rule survive.
The damage, in numbers
From the case file. 8,452 spam URLs, in two waves.
3–4 January: roughly 4,400 discovered, 900 indexed. 7–8 January: about 3,100 more discovered, none indexed — Google had recognised the pattern in between and stopped ingesting.
Final position: 900 indexed, 7,552 not indexed.
The second number looks like the good news. It’s the harder half, and here’s why.
Why the index outlives the infection
“Not indexed” mostly means discovered but never fetched. Google learned those URLs existed, from links, and never requested them.
Now think about what your cleanup does. You configure the spam URLs to return gone. That works beautifully — for URLs Google asks about.
Google cannot receive an answer to a question it never asks. For thousands of URLs that were only ever discovered, there is no request for your server to respond to. Nothing your fix does can reach them. They sit in the record until Google decides on its own to check, on its own schedule.
That asymmetry — not Google being slow, stubborn or punitive — is why this outlives everything else.
Removing it without making it worse
The status codes matter here more than anywhere else in the series. Part 3 has the full reference; these are the four decisions.
Serve 410, not 404. Both mean the page isn’t there. 404 says not here and Google keeps checking back for months in case you put it back. 410 says gone, deliberately, stop asking and clears considerably faster. When you’re removing thousands of URLs, that difference is months.
Never 301. A permanent redirect tells search engines to carry the old URL’s signals over to wherever you point it. Redirecting spam URLs to your homepage asks Google to associate that content with your front page. It’s the most common instinct and it’s actively harmful.
Never block them in robots.txt. This is the expensive one, and it feels like the fastest fix. Blocking a URL doesn’t remove it — it prevents Google from ever fetching it again, which means Google can never learn that it’s gone. Given that most of your problem is URLs Google hasn’t fetched, this takes the hard half and freezes it permanently.
And watch for your fix breaking.
From the case file. The rule correctly returning
410broke on 1 March and began returning500. A server error tells Google something’s wrong here, I’ll come back later — so the URL is retained rather than released.For as long as it was broken, every request was asking Google to hold on to a URL the site was trying to remove. The fault was invisible from the front page and cost weeks.
Check your own removal rule periodically. A cleanup that silently reverses is worse than one that never started, because you stop watching.
What to expect afterwards
Slowly. The indexed pages clear first, because Google requests them and gets your answer. The discovered-not-fetched pile clears on Google’s timetable, not yours.
Then check the residue that isn’t a search engine:
Your structured data reports, so no fabricated review markup is still validated against your domain. Search Console’s users list, since an intruder who verified ownership keeps reading your data after every server rebuild. And your backlink profile — the mesh ran across other compromised domains, and if any linked to your spam URLs, third-party link tools will have recorded them as inbound links to you. That’s a separate index that doesn’t respond to status codes at all.
The real damage
It isn’t the files. It’s that your domain spent months telling Google it was a Japanese retail store, with thousands of URLs, fabricated review markup and validated shopping results — and Google believed enough of it to index some and remember the rest.
Recovering rankings and trust after that is a different discipline from cleaning a hack, and it’s where this series hands off.
What you can do yourself, and what you can’t
Yours: the Search Console side entirely — reading the numbers, exporting the lists, checking the enhancement reports and the users list, and monitoring whether the URLs are actually clearing.
Not yours, usually: the server-side rule that produces the 410, and finding the handler that generated the pages in the first place.
But the single most valuable thing you can do here is a negative one, and it needs no access at all: don’t block them in robots.txt, and don’t redirect them to your homepage. Both feel productive. Both make it permanent.
Back: Who Do You Have to Tell After a Website Hack?
Twenty pages became eight thousand without you seeing any of it. What is still live under your name is answerable, and it is the first thing worth answering.
Start a Recovery ReviewPaid assessment · scope agreed up front
Next: Site Hardening → — what would actually have stopped this, what would have caught it eleven months sooner, and what’s worth doing anyway even though it wouldn’t have helped at all.
Hub: Invasion Investigation Blog Series
ProVAE builds and recovers websites in Douglas, Georgia, serving South Georgia.
