Your Data Doesn't Need to Be Hacked to Leak. It Just Needs to Be Scraped

The Chess.com leak wasn't a hack, it was scraping. Here's what that means for any business running a platform with user profiles, listings or public-facing data.

Your Data Doesn't Need to Be Hacked to Leak. It Just Needs to Be Scraped

When Chess.com's user data turned up exposed, the story wasn't a hacked database or a stolen password list. The evidence pointed to scraping: someone systematically pulling public profile pages and building a dataset out of information the site was already showing to anyone who asked. No exploit, no breach in the traditional sense. Just a script, patience, and a site that didn't stop it.

I mention this because I build platforms that hold user data for a living, and this is the kind of risk that gets missed. Business owners worry about hackers getting in through a back door. Fewer worry about someone walking in the front door, over and over, ten thousand times a minute.

Scraping isn't hacking, and that's exactly the problem

A breach usually means someone found a flaw: a SQL injection, a leaked credential, an unpatched vulnerability. Scraping doesn't need any of that. It just means your public pages, or your unauthenticated API, return more than they should, to more requests than they should, without anyone checking whether the requester is a person or a script running in a loop.

If your platform has:

  • public user profiles (name, location, activity, stats)
  • a directory or listings page that can be paged through endlessly
  • an API endpoint that returns data without authentication, because it's "just for the frontend"
  • sequential IDs in your URLs, like /profile/1, /profile/2

then someone can turn that into a dataset without ever touching your servers in a way your security tools would flag as an attack. Each request looks legitimate on its own. It's the volume and pattern that gives it away, and most small platforms aren't watching for that pattern at all.

Why this matters even if you're "just" a small SaaS

It's tempting to think this is a problem for platforms with millions of users. It isn't. A trades booking app with a few thousand customer profiles, a membership site with a public directory, a marketplace with seller listings, all of these hold data that's worth scraping to someone: for spam lists, competitor intelligence, or just because it was easy.

And the legal exposure doesn't scale down with the size of your user base. If customer names, emails or locations end up harvested and resold, you're the data controller who's answerable under UK GDPR, regardless of whether it was a "real" breach or a scraper nobody noticed for six months.

What I'd actually check

None of this needs exotic security tooling. It needs the same care I'd apply to any endpoint that touches real user data:

  • Rate limit everything, not just login. Public profile pages and directory listings should have sensible limits per IP or session, not just the login form. Most frameworks make this a few lines of config, there's rarely a good reason to skip it.
  • Don't use sequential IDs in public URLs. If /user/104 works, so does a loop from 1 to 999999. UUIDs cost nothing to generate and remove the easiest form of enumeration overnight.
  • Check what your "public" API actually returns. It's common for an endpoint built for one screen to quietly return the full user record because it was quicker to build that way. Trim the response to exactly what that screen needs, nothing more.
  • Paginate with limits, not just page numbers. A directory that lets someone request page 50,000 of 50 results each is still handing over your entire user base, just slowly.
  • Watch for the pattern, not just the failure. A single failed login is noise. Five thousand successful requests to sequential profile URLs from one source in an hour is a pattern worth an alert.

I've written before about how patching speed matters once a vulnerability is public, and the same logic applies here in reverse: the gap between "this looks fine in a demo" and "this is being abused in production" is often just volume. Nobody scrapes a site with three users. Everyone eventually scrapes a site with three hundred thousand.

Fixing it is usually a config problem, not a rebuild

This is the part worth knowing before you panic. Almost none of the fixes above require rearchitecting anything. Rate limiting is middleware. Switching from sequential to UUID-based public identifiers is a migration, not a rewrite. Trimming an API response is an afternoon's work once you know which endpoint is the problem.

The harder part is knowing to look. If you commissioned a platform years ago and haven't asked anyone to check it against this list since, that's worth an hour of someone's time. Not because you're necessarily exposed, but because the cost of checking is small and the cost of finding out from a data protection complaint is not.

If you're building something new with public profiles, listings or directories, it's worth raising this at the design stage rather than retrofitting it later. It's a much smaller conversation to have before launch than after.