You ask an AI to build a login system.
It writes the code.
You run it.
Signup works. Login works. Password reset works. The dashboard looks great.
You ask:
> “Is this secure?”
The AI says yes.
That's where I'd stop trusting it.
Not because AI is bad at programming. It's actually very good at programming now.
The problem is that writing code that works and proving that code is secure are two different jobs.
Recent research makes this harder to dismiss as an old AI problem. Veracode's 2026 GenAI Code Security Report says roughly 44% of its AI code-generation tasks produced code containing a known vulnerability.
A March 2026 peer-reviewed study using real developer interactions found 56 confirmed vulnerabilities across 48 files of GPT-generated code. When researchers explicitly asked newer models to find and repair those flaws, GPT-4.1, GPT-5 and Claude Opus 4.1 detected roughly three quarters or more of the issues, but none found everything.
So the interesting question isn't:
“Why is AI bad at coding?”
It's:
“Why doesn't better coding ability automatically produce secure software?”
AI optimizes for working code, not for every attacker you didn't mention
Imagine you ask:
> “Build a dashboard where users can view their invoices.”
That's a perfectly normal prompt.
The AI knows it needs:
- A login system
- A database
- An invoice table
- An API
- A frontend
It may produce all of that correctly.
But there's another question hidden inside the requirement:
Which invoices is each user allowed to see?
That question is about authorization.
And it isn't always obvious from the feature description.
Your API might end up with:
GET /api/invoices/1042
Authorization: Bearer <user-token>
The user is authenticated.
The token is valid.
The request works.
Now change:
1042
to:
1043
If invoice 1043 belongs to another customer and the API returns it anyway, you have a serious authorization problem.
The code may have been perfectly functional.
The login may be perfectly secure.
The database may be perfectly configured.
The vulnerability exists because one security assumption wasn't enforced.
This is why OWASP continues to rank Broken Access Control as the top application-security risk in its 2025 Top 10.
AI didn't necessarily “make a mistake” in the traditional sense.
It fulfilled an incomplete specification.
Security requirements are usually invisible
This is probably the biggest reason AI-generated code can be vulnerable.
Developers often tell AI what the application should do.
They don't describe everything the application must never allow.
For example:
> “Create an admin panel where administrators can delete users.”
That's a feature.
But security requires additional rules:
Only authenticated users can access it.
Only administrators can access it.
Administrators cannot delete themselves.
Administrators cannot delete users outside their organization.
Deleted users cannot access existing sessions.
The endpoint cannot be called directly by a normal user.
The API must enforce all of these rules server-side.
Humans often carry these assumptions in their heads.
The prompt doesn't.
AI can't reliably enforce requirements that were never defined, especially when those requirements depend on the architecture, deployment environment, data model, or business rules.
That's why a more powerful model doesn't automatically eliminate vulnerabilities.
The model can be brilliant and the specification can still be incomplete.
AI learns patterns, and the internet contains insecure patterns
There's another uncomfortable reality.
AI coding models learn from enormous amounts of code and technical text.
The internet contains excellent code.
It also contains outdated tutorials, vulnerable examples, Stack Overflow answers written years ago, insecure GitHub repositories, abandoned projects, and code written before today's security practices became standard.
A pattern can therefore look familiar without being safe.
Consider:
const query =
"SELECT * FROM users WHERE email = '" + email + "'";
It looks like normal database code.
It can also create SQL injection.
The safer approach is parameterized queries, for example:
db.query(
"SELECT * FROM users WHERE email = ?",
[email]
);
The important point isn't that AI can't generate the safe version.
It absolutely can.
The problem is that it can also generate the unsafe version, especially when the prompt or surrounding code gives it a familiar but insecure pattern.
A large-scale 2025 study comparing AI-generated and human-written code across more than 500,000 samples found that AI-generated code had a distinct defect profile and contained more high-risk security vulnerabilities in its evaluation.
So “the AI has seen millions of lines of code” isn't a security argument.
It can mean the model has seen millions of good patterns.
It also means it has seen plenty of bad ones.
AI can be confident and still be wrong
This is where experienced developers have an advantage.
Ask an AI:
> “Is this authentication middleware secure?”
It can inspect the function and give you a detailed explanation.
It might even sound convincing.
But security often depends on what happens outside that function.
Maybe another middleware runs first.
Maybe the reverse proxy strips a header.
Maybe the application trusts a client-controlled role.
Maybe the database query doesn't enforce tenant isolation.
Maybe the JWT is validated but the sub claim is ignored.
Maybe the cache returns one user's response to another user.
The individual function can look fine.
The system can still be broken.
The 2026 study on secure coding with AI specifically warned that LLMs can confidently provide incorrect information, which creates additional risk for less experienced developers who may accept the explanation without independently verifying it.
That's the dangerous part.
The code doesn't need to look suspicious.
It can look professional.
The frontend can make an insecure backend look secure
AI is particularly good at building polished interfaces.
That's useful.
It's also easy to mistake the interface for the security model.
Suppose the AI creates:
if (user.role === "admin") {
showDeleteButton();
}
A normal user doesn't see the button.
Looks secure.
But what stops the user from calling:
DELETE /api/users/42
directly?
Nothing, unless the backend checks the user's permissions.
This distinction is simple:
The frontend decides what the user sees.
The backend decides what the user is allowed to do.
If your security depends on a button being hidden, an attacker can usually ignore the button.
This is especially important for AI-generated SaaS applications because an agent can build the frontend and API together so quickly that the two can appear perfectly consistent while still having completely different security assumptions.
AI can fix a vulnerability and create another one
Here's something developers don't talk about enough.
You find a vulnerability.
You paste it into the AI coding agent:
> “Fix this authorization issue.”
It changes the code.
The test passes.
Great.
Except the AI also changed how the request is authenticated.
Or removed a middleware because it appeared redundant.
Or moved validation into the frontend.
Or changed an error handler and started exposing database details.
You fixed one problem and introduced another.
This is why security fixes need to be re-scanned and re-tested.
A security patch isn't finished when the AI says:
> “I've fixed the issue.”
It's finished when the security test passes.
That difference matters.
Some vulnerabilities aren't visible in the code at all
Let's say your application code is clean.
You still have a problem if:
Production database
↓
Publicly accessible
Admin panel
↓
No MFA
Cloud storage
↓
Public bucket
Staging server
↓
Old vulnerable dependency
The vulnerability may live in the configuration, infrastructure, dependency tree, deployment process, or permissions.
This is why AI code generation shouldn't be treated as the entire security problem.
Your application has multiple layers:
AI-generated code
↓
Dependencies
↓
Build system
↓
Server configuration
↓
Cloud infrastructure
↓
Database
↓
Browser
↓
Real users
A secure function can't compensate for an exposed database.
And a perfect SSL configuration can't compensate for broken authorization.
Security is a system property.
Not a property of one code snippet.
So should you stop using AI to write code?
No.
I wouldn't.
That would be like refusing to use a compiler because programmers can write bugs.
AI is incredibly useful for development.
It can write boilerplate, explain unfamiliar APIs, generate tests, refactor code, find bugs, create prototypes, and help experienced developers move much faster.
The mistake is treating generated code as trusted code simply because a powerful model produced it.
I'd use AI aggressively for development.
I'd be conservative about trusting its output.
That's a much better combination.
Give AI better security instructions, but don't stop there
A good security prompt can help.
Instead of:
> “Build a file upload endpoint.”
Try:
> “Build a file upload endpoint. Validate file type and size server-side, generate a safe server-side filename, prevent executable uploads, store files outside the web root where possible, enforce authorization on downloads, and reject access to another user's files.”
That's better.
You're giving the model a threat model.
But there's still a problem.
You have to know what security requirements to ask for.
A beginner may not know about executable uploads or object-level authorization in the first place.
That's why prompting alone isn't enough.
You can't prompt for a security property you don't know exists.
Automated scanning and security testing provide another layer.
The workflow I'd actually use for AI-generated code
If I'm building a real website or SaaS with AI, my workflow looks more like this:
AI generates code
↓
Developer reviews it
↓
Dependency + secret scan
↓
Static security analysis
↓
Automated tests
↓
Manual authorization tests
↓
Deploy to staging
↓
Scan the running application
↓
Fix findings
↓
Deploy to production
↓
Monitor continuously
Notice what's missing:
> “Ask the AI if the code is secure.”
That's not a security control.
AI can participate in the review.
It can suggest fixes.
It can explain vulnerabilities.
It can even write security tests.
But something independent needs to challenge the assumptions.
That's where automated scanners, CI checks, runtime testing, and human review earn their place.
Torlyx fits into that workflow by scanning code before deployment and checking the deployed website for vulnerabilities, availability, SSL issues, and real-browser failures. The point isn't to slow down AI-assisted development. It's to put a security check between “AI generated it” and “customers are using it.”
The real problem isn't that AI writes insecure code
This is the part I want developers to remember.
AI isn't uniquely incapable of writing secure software.
Humans write vulnerable software too.
The difference is speed.
A developer might spend two days writing a feature.
An AI agent can generate a similar feature in minutes.
That means the amount of code entering a codebase can grow much faster than the amount of code humans can carefully review.
That's the real shift.
AI has made code generation cheap. It hasn't made security verification cheap.
And that gap matters.
The research backs up the nuance. Modern models are getting substantially better at finding and repairing vulnerabilities when explicitly asked, with 2026 research showing detection and remediation rates around 75–80% in one real-world dataset. But that still leaves a meaningful fraction of issues behind.
So don't ask:
> “Is AI-generated code secure?”
Ask:
> “What security evidence do I have that this code is secure enough to deploy?”
That's a much harder question.
It's also the right one.
If you've recently built an application with AI, don't ask the model whether it's secure.
Run a code and dependency scan, test authorization with two different accounts, check for exposed secrets, then scan the deployed application before real users touch it.
That's where I'd start.