Skip to content
Sedat Özdemir
Writing

iot-security

Did You Actually Code It or Just Vibe It? The Dark Side of AI-Generated Apps

AI makes coding feel like magic, but that "vibe" can be dangerous. Let's talk about why trusting LLMs too much might break your security.

Sedat Özdemir
· 5 dk read

The other night, I was just hanging out at home and wanted to mess around with one of the new LLM models. I had this idea in my head and thought, "Let’s turn this into a web app." I opened up Cursor, asked Claude 3.5 Sonnet to "build me a simple dashboard where users can upload files and create profiles." In less than five minutes, I had this polished app—React on the front, Tailwind making it look pretty. It was honestly a bit magical. But truth be told, when you catch that "vibe," it’s easy to think everything is perfect.

That’s exactly when my grumpy inner security guy started whispering: "Sedat, did you actually check what’s under the hood?"

This is what people are calling "Vibe Coding." You get into a flow, you trust the AI’s smooth responses, and you hit that deploy button because "it just works." But in our world, there’s a massive gap between "it works" and "it’s secure." From the projects I’ve reviewed lately and the security chats I’ve been in, one thing is clear: speed is making us blind.

Why Asking for a "Login Script" is Risky

Imagine you’re grabbing coffee with a friend and you say, "Hey, can you write me a quick login page?" Your friend scribbles some code on a napkin. Would you take that napkin and immediately push it to your production server? Probably not. But for some reason, when an AI writes it, we give it a pass.

I’ll give you an example from a pentest I worked on recently. The dev team had used an LLM to write the entire authorization logic. At first glance, the code looked great—it used JWTs, everything seemed to be in its place. But there was a tiny, massive detail: the LLM only checked the isAdmin flag on the front-end. You wouldn't see the admin panel in the UI, but if you sent a direct request to the backend, the doors were wide open.

The thing is, the more generic your prompt is, the more "average" your code will be. And average code usually means security was the first thing tossed out the window to make the code run.

The Invisible Threat: Logic Flaws

AI is getting really good at syntax, but it doesn't understand your specific business logic as well as you do. Take a look at this snippet an AI might generate for you:

// A simple middleware the AI wrote "quickly"
app.post('/update-profile', (req, res) => {
  const { userId, newEmail, role } = req.body;
  
  // Update user info
  db.query('UPDATE users SET email = ?, role = ? WHERE id = ?', [newEmail, role, userId], (err, result) => {
    if (err) return res.status(500).send("An error occurred");
    res.send("Profile updated!");
  });
});

See the problem? You probably told the AI, "Make me a profile update page." It took the role field directly from the user’s request and wrote it to the database. Now, if I’m a malicious user and I just add "role": "admin" to my request, what happens? Congrats, you’ve just given me the keys to the kingdom.

The reality is this: when you're vibe coding, you're focusing on the "happy path"—how the app works when everything goes right. But you need to think about the "unhappy path." What happens when someone sends data the AI didn't expect?

I'm not saying don't use these tools—I use them every day. But don't let the "vibe" trick you into skipping the code review. Use the AI to build the skeleton, but you have to be the one to put the armor on it.

Related posts