The Day The World Went Hackers
Every junior dev with a Cursor subscription is now a full-stack engineer. The frontend is a React SPA. The backend is an Express API that Claude wrote. The auth is "we'll add that later." The Gibson is in production and nobody even knows it.
The SPA-ification of Everything
There's a pattern emerging in every greenfield project touched by Gen AI: the answer is always a single-page application.
Need a dashboard? React SPA. Internal tool? React SPA. Blog? React SPA with a headless CMS and a GraphQL layer and a Vercel deployment and 14 environment variables. The AI doesn't know how to say "this should be a static page." It knows how to generate components. So everything becomes components.
This isn't new — the JavaScript ecosystem has been doing this to itself since AngularJS in 2010. What's new is the velocity. A developer who would have taken two weeks to scaffold a bad SPA can now generate one in forty minutes. The architecture is the same. The attack surface is the same. The timeline to production went from "maybe next sprint" to "I'll deploy it after lunch."
The frontend isn't the problem. Nobody's breaking into your app through a useState hook. The problem is what the SPA talks to.
The API Behind the Curtain
Every SPA needs a backend. The AI is happy to generate one. Express, FastAPI, Next.js API routes, Supabase edge functions — pick your poison. The LLM will scaffold endpoints, wire up a database, and even write middleware. It will produce code that runs, that handles the happy path, that returns 200 OK with correctly shaped JSON.
What it won't do — unless you specifically, explicitly, repeatedly ask — is:
- Validate that the user making the request is who they claim to be
- Check that the authenticated user is authorized to access this specific resource
- Rate-limit the endpoint
- Sanitize inputs before they hit the database
- Return appropriate error codes instead of stack traces
- Log access patterns for audit
The AI generates functional code. Functional is not the same as secure. Every auto-generated /api/users/:id endpoint that doesn't check whether the requesting user should see that record is an IDOR waiting to happen. And IDORs are the number one API vulnerability on the OWASP API Security Top 10 for a reason — they're trivial to exploit and invisible to anyone who doesn't think adversarially.
The Gibson Geometry
In Hackers (1995), the Gibson is a monolithic supercomputer. One big target. You break in, you own everything. It's a Hollywood fantasy from an era when "hacking" meant social engineering a phone switch.
The modern Gibson is distributed. It's not one server — it's thirty microservices, each with its own API surface, each generated by a different LLM session, each deployed by a different team member who "got it working." The aggregate attack surface isn't a single door with a bad lock. It's a building where every room has a door and half of them don't have locks at all.
This is the geometry that Gen AI creates. Not one big vulnerability — thousands of small ones, spread across services that were never audited as a system because they were never designed as a system. They were prompted into existence, one endpoint at a time.
The Checklist That Should Be Boring
API security isn't glamorous. It's a checklist. That's the point. If you're shipping endpoints — especially AI-generated ones — and you're not doing all of the following, you're running a Gibson:
Authentication: Every endpoint knows who's calling. JWTs, session tokens, API keys — pick one and enforce it everywhere. Not "on the routes that seem important." Everywhere. Middleware, not per-route decoration.
Authorization: Authentication tells you who. Authorization tells you whether. Your /api/invoices/1547 endpoint should not return data just because the request has a valid token. It should verify that the token's owner has access to invoice 1547. This is object-level authorization and it is the single most common API vulnerability in production.
Input validation: Every field, every parameter, every header. Zod, Pydantic, JSON Schema — the library doesn't matter. What matters is that ?limit=99999999 doesn't dump your entire database and name=<script>alert(1)</script> doesn't end up in someone else's browser.
Rate limiting: If your API doesn't rate-limit, you've given every attacker on earth unlimited free attempts to find what you missed. Token bucket, sliding window, pick an algorithm. Apply it at the gateway, not the application layer, so it can't be bypassed by hitting a different route.
Error handling: Your 500 response should not include a stack trace, a database connection string, or the ORM query that failed. In production, errors are opaque to the caller and verbose to your logging pipeline. The attacker learns nothing. Your oncall learns everything.
Transport: TLS everywhere. Not "we'll add HTTPS later." Not "it's an internal service." TLS. HSTS headers. Certificate pinning if you're mobile. This is 2026 — plaintext HTTP in production is malpractice.
CORS: Your SPA is on app.example.com. Your API is on api.example.com. If your CORS policy is Access-Control-Allow-Origin: *, you've just told every domain on the internet that it's welcome to make authenticated requests to your API from a user's browser. Set the origin. Set the methods. Set the headers. Be explicit.
None of this is novel. None of this is hard. All of it gets skipped when the development cycle is "prompt, verify the happy path, deploy."
The Vibe-Coded Pentest
Here's a experiment. Take any SPA that was built primarily with AI assistance. Open your browser's dev tools. Go to the Network tab. Click through the application.
You'll see every API call. Every endpoint. Every parameter. The request headers, the response shapes, the auth tokens. The SPA is a map of the backend. The browser is the pentest tool. This isn't a sophisticated attack — it's reading the network tab that every browser ships.
Now change an ID in one of those requests. /api/projects/47 becomes /api/projects/48. Did you get someone else's data? If yes, congratulations — you've just confirmed a Broken Object Level Authorization vulnerability that the AI never thought to prevent because you never prompted it to.
The AI will write you a fetchProject(id) function. It will not write you a verifyProjectAccess(userId, projectId) function unless you ask. And if you don't know to ask, you ship the Gibson.
The Structural Problem
This isn't about AI being bad at security. It's about the default path. When you ask an LLM to "build a REST API for managing users," the default output is CRUD operations that work. Working is the objective function. Security is a constraint that has to be explicitly added.
The pre-AI version of this problem was the same, but slower. A junior dev would copy a CRUD tutorial, skip the auth section, and ship it. The senior dev would catch it in code review. The cycle time was days or weeks — enough time for the review to happen.
Now the cycle time is minutes. The code goes from prompt to production in an afternoon. The code review is the developer reading the AI's output and checking whether it works, not whether it's secure. And if the reviewer is also using an AI to review the code — which, increasingly, they are — you've got the Abstraction Debt Law in full effect: AI-assisted velocity outpacing security discipline, with nobody in the loop who's thinking adversarially.
What Actually Helps
Threat modeling before prompting: Before you ask the AI to build anything, spend ten minutes asking: who should access this? What happens if someone unauthorized accesses it? What's the worst thing a malicious input could do? These questions shape the prompts. The AI is good at implementing security — when told to.
Security requirements in the prompt: "Build a REST API for managing invoices. Every endpoint must verify that the authenticated user owns the requested invoice. Return 404, not 403, for unauthorized access to prevent enumeration. Rate-limit to 100 requests per minute per user." The AI will do this. You just have to ask.
Automated scanning in CI: OWASP ZAP, Semgrep, Snyk — tools that check for the things humans forget. Run them on every pull request. If the AI generated an endpoint without auth, the scanner catches it before production does.
API gateways: Put your auth, rate limiting, and CORS at the gateway level. Kong, Envoy, even Cloudflare Workers. When security is infrastructure, it can't be skipped by a developer who forgot to add middleware.
Hack the Planet, Responsibly
The irony of Hackers is that the heroes were the hackers. They found the vulnerabilities. They exposed the fraud. The system was corrupt and the kids with the modems were the ones who fixed it.
In 2026, the system isn't corrupt — it's just moving too fast. The kids with the LLM subscriptions aren't malicious. They're building real things, solving real problems, shipping real products. They're just not thinking about the people who will be malicious, who will open the Network tab, who will increment the ID.
You don't have to slow down. You have to secure the surface you're generating. Every endpoint gets auth. Every input gets validated. Every error gets sanitized. Every deployment gets scanned. This isn't overhead — it's the cost of shipping code that a machine wrote and a human signed off on.
The Gibson was funny in 1995 because it was fiction. It's less funny when it's your API returning customer PII to anyone who guesses an integer.
Don't build the Gibson. And if you do — at least put a lock on the door.
✌️☮️
The blog you're reading this on has zero API endpoints. It's one AWK file serving static HTML behind Cloudflare. The attack surface is exactly as large as it needs to be and not one byte larger.