Your AI Thinks You're a Genius (It's Lying)
LLMs agree with you up to 60% of the time even when you're wrong. Here's why sycophancy is AI's most dangerous default.
53% of teams shipping AI-generated code later found security issues that passed initial review. Here's what's going wrong and how to fix it.
Muunsparks
2026-04-01
Moltbook was a social network run entirely by AI agents. Bots posted, replied, and interacted without human intervention — and for a few days in early 2026, it was the most fascinating experiment on the internet. Then Wiz released a report: a misconfigured database had exposed 1.5 million API authentication tokens and 35,000 email addresses to the public internet. The founder's public statement made the cause clear — he hadn't written a single line of code. Every line was vibe-coded.
That's the story the industry keeps not learning from.
Vibe coding — describing what you want in plain language and letting an AI generate the implementation — has genuinely collapsed the distance between idea and working software. Gartner projects 60% of new code will be AI-generated by end of 2026. That productivity story is real and the tools are impressive.
The security story running underneath it is not impressive.
Security startup Tenzai spent December 2025 methodically testing five of the most widely used AI coding tools — Claude Code, OpenAI Codex, Cursor, Replit, and Devin — by prompting each to build three identical web applications from the same specs. Across all 15 apps, they found 69 vulnerabilities. Every single tool introduced Server-Side Request Forgery (SSRF) vulnerabilities. Not one app built CSRF protection by default. Not one set security headers.
Escape.tech went broader: scanning 5,600 publicly deployed applications built on vibe coding platforms like Lovable, Bolt.new, Base44, and Create.xyz. They found over 2,000 vulnerabilities, 400+ exposed secrets (API keys, credentials, and tokens sitting in accessible frontend bundles), and 175 instances of personally identifiable information — medical records, IBANs, phone numbers — exposed through public endpoints.
Carnegie Mellon put a precise number on the structural problem: 61% of AI-generated code is functionally correct. Only 10.5% is secure.
That gap — between "it works" and "it's safe" — is what the vibe coding workflow is systematically hiding from you.
This isn't a model quality issue that will be solved in the next release. It's an incentive problem baked into how vibe coding tools are built and how developers use them.
AI coding assistants are optimized for a single outcome: producing code that satisfies the prompt. That means functional output, fast. What it doesn't mean is code that handles what happens when your assumptions are wrong — when user input is malicious, when a request tries to access another user's data, when a third-party API key ends up in a client-side bundle.
Security requires thinking adversarially. It requires asking "what could go wrong?" before asking "does this work?" The vibe coding loop — describe, generate, test in browser, ship — has no natural insertion point for that question.
Three specific failure modes show up consistently in the research:
The most dangerous vibe coding vulnerability category isn't the dramatic ones — it's broken authorization that only surfaces under specific conditions. An AI generates an API endpoint that correctly returns data for the authenticated user, but the user ID is taken from the request parameter rather than the session. It works perfectly in your tests because you're testing as yourself. It falls apart the moment a user changes the ID in the URL and reads someone else's data.
// What AI commonly generates — looks correct, is not
app.get('/api/user/orders', async (req, res) => {
const { userId } = req.query; // ❌ attacker-controlled
const orders = await db.orders.findMany({ where: { userId } });
res.json(orders);
});
// What it should look like
app.get('/api/user/orders', async (req, res) => {
const userId = req.session.userId; // ✅ server-controlled
const orders = await db.orders.findMany({ where: { userId } });
res.json(orders);
});
Georgetown's CSET found that 86% of AI-generated code fails XSS defense mechanisms. The same pattern holds for IDOR (Insecure Direct Object Reference) vulnerabilities — they're structurally invisible until someone actively looks for them.
Lovable's CVE-2025-48757 incident exposed this at scale: researchers found 170 out of 1,645 scanned Lovable-generated apps — 10.3% — had Supabase service keys directly retrievable from the frontend JavaScript bundle. Not buried. Trivially retrievable. The apps were handling real user data.
This happens because AI tools will use whatever connection pattern gets the app working. Supabase's client-side SDK requires the anon key; if you're prompting for a quick implementation, the model grabs the service key because it has broader permissions and the app works immediately. That distinction — anon key vs. service key — requires security knowledge to catch and is essentially invisible in a vibe coding workflow.
Vibe coded apps pull in packages automatically. The model picks libraries that solve the stated problem, without checking CVEs, without pinning versions, without evaluating whether that library has been maintained in the last two years. The Veracode GenAI Code Security Report found AI introduces OWASP Top 10 vulnerabilities in 45% of generated code samples — with Java hitting over 70%. Supply chain risk is a large part of that number.
The instinct is to add a review step at the end. That instinct is wrong, and Tenzai's researchers said it directly: "Debugging assumes humans can meaningfully review AI-generated code after the fact. At the scale and velocity of vibe coding, that assumption collapses."
The fix is moving security into the act of creation, not bolting it on downstream. Here's what that looks like in practice:
Databricks' AI Red Team found that self-reflection prompts can improve the security profile of generated code by 60-80% for Claude and up to 50% for GPT-4o. The tools can find their own vulnerabilities when asked. Add a standing instruction to your project context:
# Security Requirements (include in every AI coding session)
Before generating any code that handles user data or auth:
- Use server-side session values for user identification, never request parameters
- Never hardcode credentials or API keys; use environment variables
- Add input validation for all user-supplied data
- Flag any use of eval(), dynamic SQL construction, or innerHTML assignment
- Prefer parameterized queries over string interpolation
After generating: review the output for OWASP Top 10 patterns before I accept it.
This sounds obvious. Most developers don't do it because the vibe coding loop rewards speed and this slows the loop. Do it anyway.
Static analysis won't catch everything — it won't catch the broken authorization example above, because that requires understanding business logic. But it catches the low-hanging fruit that accounts for a significant portion of AI-generated vulnerabilities: hardcoded secrets, known-insecure function calls, dependency CVEs, missing security headers.
Semgrep is the practical choice here. It runs fast, integrates with every major CI system, and has rulesets specifically built for common AI-generated code patterns. There's an MCP server for it now, which means you can embed it directly into your Cursor or Claude Code workflow rather than treating it as a post-generation gate.
# .github/workflows/security.yml — minimal viable security gate
name: Security Scan
on: [pull_request]
jobs:
semgrep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: returntocorp/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/secrets
p/javascript
Static analysis misses logic errors. The only thing that catches logic errors is tests that probe the actual behavior of your application, written with an adversarial mindset.
For auth and authorization specifically, write tests that verify what an unauthenticated user cannot do, and what User A cannot do to User B's data. These tests are boring to write and critical to have. Playwright handles this well because it supports multi-session testing — you can run a logged-in session as User A and verify that User B's session cannot access the same resources.
// Playwright test: verify IDOR protection
test('user cannot access another user\'s orders', async ({ browser }) => {
const userA = await browser.newContext();
const userB = await browser.newContext();
// Get User A's order ID after login
const pageA = await userA.newPage();
await loginAs(pageA, '[email protected]');
const orderResponse = await pageA.request.get('/api/user/orders');
const { orders } = await orderResponse.json();
const orderIdBelongingToA = orders[0].id;
// Attempt to access it as User B
const pageB = await userB.newPage();
await loginAs(pageB, '[email protected]');
const crossUserResponse = await pageB.request.get(
`/api/orders/${orderIdBelongingToA}`
);
// This should fail — if it returns 200, you have a vulnerability
expect(crossUserResponse.status()).toBe(403);
});
If you're shipping vibe-coded apps without tests like this, you're not testing whether your app is secure. You're testing whether it works when nobody's trying to break it.
The tools are genuinely getting better. Claude Code scored the lowest number of high-severity vulnerabilities in the Tenzai study — 4 high-severity flaws versus significantly more for other tools. The gap between best and worst performers is real and widening. Anthropic, OpenAI, and Cursor are all actively working on security-aware generation.
And 63% of vibe coding users are non-developers. For that population, a vibe-coded app with some vulnerabilities is still better than no app — because the alternative isn't a security-hardened custom implementation, it's a spreadsheet or a manual process. The risk profile calculation is genuinely different depending on who's building what.
The problem is when developers — people who do understand the threat model — treat vibe coding output as production-ready without a security pass. That's where the Moltbook situations come from. Not from non-developers being naive, but from developers moving too fast and assuming the AI handled it.
The productivity gains are real, the security gap is structural: AI coding tools optimize for functional output, not secure output. That's not changing in the next model release — it's an incentive problem requiring a process fix.
Add security context to every session: Self-reflection prompts improve AI security output by up to 80%. Make security requirements part of your standing project context, not an afterthought.
Static analysis catches the obvious; behavioral tests catch the dangerous: Run Semgrep in CI for known patterns. Write Playwright tests that probe authorization flows with adversarial intent — especially IDOR scenarios where a user accesses another user's resources.
Review auth logic as if you wrote it yourself: Authorization flaws are the hardest for AI to get right and the easiest to miss in review because the happy path works correctly. Always trace user identification back to the session, not the request.
The Moltbook lesson generalizes: If you didn't write it, you still own it. Vibe coding shifts who generates the code; it doesn't shift who is responsible for what that code does in production.
Tags: vibe-coding, security, ai-generated-code, devsecops, cursor
// RELATED ARTICLES
LLMs agree with you up to 60% of the time even when you're wrong. Here's why sycophancy is AI's most dangerous default.
Stop screaming into the void of the algorithm. In 2026, your content is only as good as the first 1.8 seconds. If your hook doesn't stop the scroll, the rest of your post doesn't exist. We’ve curated 10 battle-tested, copy-paste AI prompts designed to engineer curiosity gaps, trigger psychological "scroll-stops," and turn passive scrollers into active readers. Whether you're on LinkedIn, X, or Instagram, these are the frameworks you need to master the art of the viral opening.
AI employees are real and fragile. Here's a practical engineering guide to building agentic workflows that survive production in 2026.