Posts / open-source

The Gap Between 'Open Source Project' and 'Hosted Service' Is Bigger Than You Think


There’s a story doing the rounds this week that I keep coming back to. A developer built an open source project management tool called Kaneo, stood up a cloud-hosted version so people could try it without wiring up their own database, and then one Thursday morning discovered that a botnet had used his signup flow to send 14,520 phishing emails in a three-hour window. From his verified domain. To real people who had no idea what Kaneo was.

No exploit. No vulnerability in the traditional sense. Just a signup flow that was designed to be easy, being used exactly as designed.

The write-up is worth reading in full. What I find genuinely interesting isn’t the technical detail, though that’s solid. It’s the framing. The developer makes this observation that cuts right to it: he’d built the signup flow while thinking like someone who wants to try the product. He hadn’t spent five minutes thinking like someone who wants to abuse it.

That’s not a stupid mistake. It’s the default mode. When you’re building something, you’re thinking about the happy path because that’s what you’re trying to make work. Security thinking is a different lens entirely, and switching between them doesn’t come naturally, especially when you’re one person shipping a side project.

I’ve been in and around software development long enough to recognise that gap. The threat model for “people I know evaluating my tool” and “anonymous public internet” are completely different things, and it’s easy to not update your thinking when you cross that line. You push a hosted version up and in your head it’s still just the project, but it’s not. It’s a service now. Different rules apply.

The comment threads around this story predictably turned into a debate about AI-assisted development, which feels like a bit of a detour. The developer uses tools like Claude and Codex during development, same as a lot of people do now, and some commenters treated that as the root cause. One commenter said it more clearly than I would have bothered to: the thinking precedes the code. A developer who doesn’t ask “what can an attacker do with this flow” will produce a vulnerable flow whether they’re using AI assistance, writing everything from scratch, or pair-programming with someone. The tool isn’t the problem. The frame is the problem.

That said, the concern about AI-assisted development enabling people to ship production services before they’ve developed the intuition to run them isn’t entirely wrong. There’s a real difference between “I built this to understand whether the idea has legs” and “I’m now operating an email-sending service on behalf of anonymous users.” The first is fine. The second carries obligations. The problem is there’s no clear moment when you cross from one to the other.

The bit that’s stuck with me most is a line from the write-up about the gap between “open source project” and “hosted version of an open source project.” He says he hadn’t been treating that gap as seriously as he should have. I think a lot of people running small hosted tools on the side are in the same position. You’ve got a Postgres instance somewhere, a domain, a transactional email provider, and a signup flow, and somewhere in the back of your head you’re still thinking of it as your little project rather than a public service that real people and real bad actors will interact with.

One practical thing that came out of the comments: the patchwork of tools you need to defend against this kind of abuse is annoying to assemble. Captcha here, disposable email detection there, rate limiting, content filtering. Each piece exists. Nobody’s really bundled them into something an indie developer can drop in without a week of integration work. That feels like a genuine gap.

The developer handled it well: cleaned up, wrote it up honestly, updated the defences. The 14,000 people who received phishing emails from a domain they’d never heard of had less of a good time. Some of them probably clicked something they shouldn’t have.

That’s the part that sits uncomfortably. The developer will be fine. The project will probably be fine, maybe better for it. The people on the receiving end of those invitations didn’t sign up for any of this, and there’s not much the developer can do for them now. He deleted the data before he’d thought through whether notification was possible.

I don’t say that to pile on. I’d probably have made the same call under pressure. But it’s worth sitting with: when something goes wrong with a hosted service, the blast radius extends well beyond the person running it.