This issue: Some practical notes for attacking vibe coded apps.

If you like practical stories about AI and offensive security, subscribe to Cred Relay.

I came across a bug where the app enforced authentication with a JWT. But it only checked that the JWT existed and didn’t validate it’s signature. To make it worse it would determine your identity and permissions based off the JWT. I was able to forge a JWT and takeover the application. Because of the nature of this particular app it became a full Entra tenant compromise. I was able to become the service principal and used that access to add a secret to another SP account and eventually got to one with global administrator privileges.

Vibe coding is everywhere. I keep finding bad stuff. Mostly exposed secrets but tons of authorization issues too.

I’m not the only one seeing this. Georgia Tech’s April write-up on Vibe Security Radar says researchers scanned more than 43,000 public security advisories and confirmed dozens of AI-linked vulnerabilities, including authentication bypass, command injection, and SSRF.

Escape says it scanned 5,600 public vibe-coded apps and reported more than 2,000 vulnerabilities, 400-plus exposed secrets, and 175 instances of exposed PII.

Agents write code token by token with no model of who's allowed to do what. The controls that depend on holding a boundary across requests are exactly the ones that break.

Can you just adjust your prompts to fix this?

You can reduce the rate of these errors being introduced but its a silent failure and easy to miss. You can have it check for all the things mentioned in this article and it will be good at detecting those for that session but as other team members contribute code from their agents these things can return. It will happily write an ownership check that looks right and enforces the wrong thing, because it has no ground truth for whose data is whose. How do we fix this? Pen testing. It’s built for and thrives on these edge cases.

This is great news if you’re a pentester like me. Let’s cover where to find these bugs.

1. Token signing

This one feels like slinging NTLM creds with SMB signing disabled. It’s an easy win and it’s pervasive. Grab /.well-known/openid-configuration if it's there. It maps out much of the identity attack surface: the issuer, supported ID-token signing algorithms, and the jwks_uri where verification keys are published. Then just forge your own JWT and see what happens.

Forging a JWT is easy and you may have covered them in CTFs, DVWA or crAPI. If you aren’t familiar with attacking them I suggest you start with TrustedSec’s resource on the topic here: https://trustedsec.com/blog/keys-to-jwt-assessments-from-a-cheat-sheet-to-a-deep-dive and OWASP has a good article here.

2. Exposed secrets and convenience endpoints

Secrets are pretty straightforward. Check for an .env served straight from web root, look at the bundled JS for keys baked into the frontend, and read the source maps if they shipped, since those hand you the pre-build code with secrets still in it. The .env file is the big one.

Many developers create convenience endpoints to generate JWTs in test environments and forget about them. I’ve seen a ton of endpoints that return a JWT without authentication. Usually /api/token or similar. And hey if it gives you the token then you don’t need to forge one. Be sure to check the permissions and claims of the JWT for lateral movement possibilities. I typically use jwt.ms.

3. Authorization

Many vibe coded apps will just assume if a session is present then the authorization is good. Authentication, authorization, it’s all the same thing right? This is what the agent thinks and if authentication is good then the rest is probably fine.

Test it in two directions. Horizontal first: as a normal user, try to reach another normal user's data. Swap the identifier the app trusts (user ID, org ID, project ID, tenant ID) in the path, body, or query, and see if the server objects or just serves it. That's IDOR / BOLA, and vibe-coded apps are full of these because the agent wired up the query but never the ownership check. Then vertical: from that same low-priv user, try to reach admin routes and admin actions directly. Often nothing stands between a logged-in user and /admin except the frontend not showing the link.

Each row is the same failure.

What is present

What must be proved

Fast abuse case

JWT or bearer token

Signature, issuer, audience, expiry, and subject

Tamper the payload, use an expired token, or swap identity claims

Authenticated session

Object ownership and role authorization

Swap user, org, project, or tenant IDs

Tenant ID or public anon key

Server-side tenant scope and effective RLS

Query or modify another tenant’s rows directly

User-controlled URL

Allowed scheme, destination, redirects, and egress policy

Fetch localhost, private IP space, or redirect to it

File path or upload name

Canonical path boundary and ownership

Try traversal, absolute paths, symlink escapes, or cross-user files

AI/tool request

Constrained capability before fetch, files, shell, plugins, or eval

Use prompt or parameter injection to cross the intended tool boundary

Agents struggle with boundaries. At least they do for now. Better prompting and guardrails mitigate some of it. But this still leaves a goldmine of edge cases for pentesters.

Cred Relay is where I write about AI, offensive security, and the messy work behind real findings. Subscribe if you want the next one.

Got questions, corrections, or want to argue? Hit reply. I read everything.

— Jeff

Keep Reading