7 min read

When AI makes every hidden door worth trying

Published on Thu Sep 24 2026

I’m slightly obsessive about one question whenever I look at a system: who can reach this? There’s a second question sitting just behind it though, and it’s the more dangerous one: What have I agreed to trust without ever choosing to?

Most teams are pretty good at answering the first question. We know who has accounts, which ports are open, roughly where the production systems live and who is supposed to have access to them. The second question is much harder, because the trust that causes trouble is often invisible. It arrives bundled with a platform and switched on by default, buried inside some feature nobody remembers enabling. It doesn’t feel like a security decision because nobody consciously makes it.

For a long time, that was a risk most teams could reasonably live with. Finding and exploiting obscure behaviour took time and skill, so most attackers had to choose their targets carefully. AI has changed that equation. When trying something costs almost nothing, everything within reach will eventually be tried, thousands of times over, with each attempt tweaked slightly until something works.

At that point, a cleverer login screen or another layer of monitoring matters less than making sure the attacker can’t reach the thing in the first place. That principle is why I moved my own development infrastructure, and most of my clients’ work, off the public internet years ago.

GitLab recently provided a good example of why.

GitLab gives every user a private email address for each project, so they can report problems by email. It sounds harmless enough, the sort of feature most people probably never notice exists. Researchers at Aikido Security found that this address could do considerably more than report an issue. Change part of the address and an email could be used to submit code changes to projects the account could access.

In effect, the address is a credential, and that changes the nature of the feature completely. There’s no conventional login involved, the sender doesn’t have to pass the second authentication step that many people rely on to protect their account, and corporate network restrictions don’t help either because nobody is connecting through the normal login flow. If somebody has that address, GitLab treats the resulting action as coming from the account it belongs to.

Worse, the address doesn’t expire. In a single afternoon, Aikido found a dozen live addresses in public READMEs, contributing guides and support pages. Nearly all of them had been published on purpose, quite reasonably, by maintainers telling people where to send bug reports. Nobody thought they were publishing something that could later be used to change code, and that is exactly the sort of hidden trust I worry about.

The organisation using GitLab didn’t consciously decide, “We’re comfortable treating possession of this obscure email address as authority to submit code.” It came with the platform, and that’s what makes the next part so uncomfortable.

Modern software teams automate an enormous amount of their delivery process. A developer makes a change, automated tests run, somebody reviews it, and the software eventually makes its way into production. That automated pipeline, often called CI/CD (continuous integration and continuous delivery), is one of the best improvements to software development in my career. Shipping small changes quickly is usually safer and much easier to reason about than doing enormous releases every few months.

But the whole system depends on one fairly important assumption: the code entering that process actually came from somebody who was supposed to put it there.

Imagine somebody gets hold of one of these addresses and submits a tiny change to the code responsible for processing customer details. The application still behaves normally and the data is still saved where it should be saved, but another copy quietly goes somewhere else. Tests still pass because the software still works.

The commit appears to come from a real developer, so a colleague reviewing it sees a familiar identity attached to the change. The automated checks are perfectly happy, and the deployment pipeline then does exactly what it was designed to do: it ships the change. From that point on, customer information could be leaking while every system inside the company reports that everything is healthy.

This is the part that frightens me. Nothing necessarily breaks, and there may be no error message, failed login or obviously malicious activity for a security tool to notice. Every individual system believes it is doing something legitimate.

For a company processing personal data, the consequences could be enormous. The breach grows every day it remains unnoticed, while the legal and reputational damage belongs to the company running the service. Yet the company may never have known this particular trust relationship existed in the first place.

When Aikido first reported the behaviour, GitLab treated it as intended functionality. GitLab has since changed how the feature is described and is considering checking that emails actually come from the account owner. Whether this counts as a vulnerability interests me less than the fact that the capability existed at all, and that so many users had no idea they had agreed to trust it.

That’s the problem with large hosted platforms. Along with the features you actively use, you’re trusting all the others too: the integrations, compatibility layers and APIs, the conveniences somebody added years ago, and the obscure features someone inside the platform thought might be useful.

AI makes that much more important than it used to be. Nothing about the attack I’ve described is fundamentally new. Attackers have searched for exposed credentials forever, and malicious code changes aren’t new either. What has changed is the cost.

Searching thousands of public repositories for interesting information used to take time. Understanding somebody else’s codebase well enough to write a convincing change used to require a reasonably skilled engineer, and matching the surrounding coding style took work. Now an AI model can do most of that very quickly.

An attacker no longer has to understand every system they target. A rough idea of what they’re looking for and enough automation to keep trying will do. Scan thousands of repositories, find something interesting, feed the surrounding code into a model and ask for a small change that looks like it belongs there. If that attempt fails, try another version, then do the same thing against the next target.

This is the same economic shift I described with phishing in The AI apocalypse is a distraction. Generating a convincing scam email used to cost somebody time. AI drove that cost towards zero, so attackers can send better scams to more people. The same thing is now happening deeper inside the systems that build and ship software, where businesses are far less likely to notice it.

The economics matter because attackers don’t need a high success rate when attempts are practically free. If one attack in ten thousand works, that might have been a terrible business model when every attempt required a skilled person. It looks very different when software can make the ten thousand attempts for you.

So the old advice of trusting a large provider because they have a bigger security team looks increasingly incomplete. A company like GitLab has talented engineers and serious security resources, and I don’t doubt that for a second. But moving something to a large hosted platform doesn’t only give you their security expertise. It also gives you their attack surface, every door into their platform that an attacker might try.

You inherit their features, defaults, integrations and assumptions. Every one of those things becomes part of your security model whether you asked for it or not, and personally I don’t like that trade. For systems I care about, I’d rather reduce the number of people who can reach them at all.

My own projects run on a privately hosted Gitea server, along with most of the client work I manage. Gitea does the same basic job as GitHub or GitLab. It stores Git repositories, tracks changes, handles issues and gives developers somewhere to collaborate. The important difference is that mine isn’t sitting on the public internet.

The servers live behind Tailscale, which creates a private network between specific devices. My laptop, servers and authorised client machines can communicate with each other wherever they happen to be, but somebody randomly scanning the internet doesn’t see those services at all. There’s no public Gitea login page to attack and no obscure email feature waiting for somebody to discover it.

It also changes what a stolen password is worth. On its own, a Gitea password isn’t enough, because an attacker has to get onto the private network first. Even being on that network doesn’t automatically give somebody access to everything, because I can define exactly which people and devices are allowed to reach which systems.

A contractor working on one client’s project doesn’t need to see another client’s infrastructure, so they don’t. Those access decisions are explicit, and that matters to me far more than having another hundred security features. I want to know who can reach something and why.

I also want the security to be boring enough that nobody is tempted to disable it, because that part gets overlooked constantly. I’ve seen plenty of beautifully designed security systems fail because they annoyed the people expected to use them. If every deployment requires fighting with a VPN client or jumping through six authentication steps, somebody will eventually find a shortcut.

My setup mostly disappears after it has been configured. The laptop connects to the private network and the tools work exactly as they normally would, so nobody has a reason to bypass it.

Running things privately doesn’t make you invincible. Software still needs patching, accounts still need protecting, and a stolen laptop that’s already authorised on the network is still a security incident.

But private infrastructure changes something much more fundamental: it changes who gets to try. Instead of every person and automated system on the internet being able to knock on the door, the potential attackers are reduced to the small set of devices and people I have deliberately allowed onto the network. That is a security property I understand.

As AI keeps making attacks cheaper to build and repeat, that property becomes more valuable every year. There will always be a new vulnerability, or a platform feature that turns out to have security consequences nobody expected. I’d rather not depend entirely on every one of those things being perfect.

If something doesn’t need to be publicly reachable, I don’t put it on the public internet. The internet spent years teaching us that everything should be accessible from everywhere, but I think AI is going to push a lot of engineers back in the opposite direction.

When attacking something becomes almost free, being difficult to attack is useful. Not being there to attack in the first place is better.

artificial-intelligence3cybersecurity2gitea1gitlab1infrastructure1security2self-hosting1software-development1tailscale1zero-trust1