Securing AI generated code is a problem I now think about on basically every pull request, because a real share of the diffs I review started life in a model. The code usually runs. It usually passes the happy-path tests the author asked for. And it quietly carries the same handful of security mistakes over and over, because the model learned from a corpus full of those exact mistakes. If you treat model output as trusted just because it compiles, you are going to ship holes.
Why the bugs cluster
Language models produce the most statistically likely code, and the most likely code is not the most secure code. The internet is full of tutorials that concatenate strings into SQL, examples that disable certificate verification to make a demo work, and snippets that log secrets without a second thought. The model absorbed all of it. So the vulnerabilities you see in generated code are not random. They cluster around the same patterns, which is actually good news, because patterns are something you can systematically catch.
I have learned to read AI output with a specific suspicion. It tends to be optimistic. It assumes inputs are well formed, that the network behaves, that the caller is friendly. Real systems are none of those things, and the gap between the model's optimism and reality is exactly where the security work lives.
The repeat offenders I watch for
Over time I built a short mental checklist that I run against any generated diff before it gets near main. None of this is exotic. It is the same list a careful engineer would use anyway, just applied with extra paranoia because nobody fully owns the reasoning behind the code.
- Unparameterized queries and any place user input gets stitched into SQL, shell commands, or file paths.
- Missing input validation at trust boundaries, especially anything coming from a request body or URL.
- Secrets and tokens that ended up hardcoded or written into logs.
- Auth checks that are present in the obvious handler but missing on a sibling route the model added.
- Disabled TLS verification, permissive CORS, or overly broad permissions that 'just made it work'.
- Dependencies the model invented or pulled in, which may be unmaintained, typosquatted, or simply wrong.
Dependencies are the sneaky part
That last bullet deserves its own paragraph. Models hallucinate package names. They suggest libraries that sound right but do not exist, or worse, that do exist and are malicious because someone registered the plausible name knowing this would happen. I never let a generated import through without checking the package is real, maintained, and the one I actually meant. A lockfile and an automated audit step catch a lot of this, but the first line of defense is a human noticing an unfamiliar name in the diff and stopping to ask where it came from.
Automate the floor, keep humans on the ceiling
You cannot eyeball every line at the volume teams now generate, so the floor has to be automated. Static analysis, secret scanning, and dependency auditing belong in the pipeline, running on every pull request, blocking merge on real findings. These tools are not smart, but they are tireless, and they catch the boring mistakes that make up most of the risk. Set them up once and they pay you back forever.
What you cannot automate is judgment about intent. A scanner will not tell you that an authorization check is technically present but checks the wrong resource, or that a feature exposes data it should not because the model did not understand the domain. That is human review work, and it is precisely the kind of review that gets skipped when a diff looks clean and the author is in a hurry. I push hard to keep that review honest, because clean-looking generated code is the most dangerous kind.
Make the author own it
The cultural fix matters as much as the tooling. On teams I work with, the rule is simple: if you submit it, you own it, regardless of who or what wrote it. 'The model generated that' is not an explanation in a postmortem. The moment people internalize that they are responsible for code they did not personally type, the quality of their review of generated output goes up sharply. They stop skimming and start reading, because their name is on the merge.
Generated code is a genuine accelerant and I use it daily. But speed without a security floor just means you reach the incident faster. Build the automated checks, keep real human review on the parts that need judgment, and make authorship mean something. Do that and you get most of the upside without quietly handing attackers a faster path in.
Building something where this matters?
I am open to senior full-stack, Web3, or AI engineering roles, fully remote and any timezone. If the hard part of your product is fighting you, that is the work I like.
Get in touch →