AI Didn't Invent New API Attacks. It Made the Old Ones Cheap.
What an AI-driven probe looks like in your logs, and the five checks that stop most of it.
Enumeration, credential stuffing, scraping and injection are not new. Most of them are older than the frameworks you’re running them against.
What changed is who runs them. An AI agent will try every ID, every parameter and every forgotten route at 2 a.m., without getting bored, for the cost of a few API credits. The basics you meant to get to later are now the whole attack surface.
The numbers back that up:
- 53% of all web traffic in 2025 was automated. Humans are now the minority.
- 27% of bot attacks in 2025 went straight at API endpoints, not web pages.
- AI-driven bot attacks grew 12.5× from 2024 to 2025.
- In a large study of 100 models, 45% of coding tasks introduced a security flaw. Your copilot writes fast; it doesn’t write safe by default.
The danger isn’t magic. It’s volume and speed aimed at the gaps every small team has: missing ownership checks, no rate limits, no logs.
Ten minutes, one agent
Here’s what an AI-driven probe looks like in your request logs. It’s an illustrative composite of common patterns, not real customer traffic.
| Time | Request | Status | What happened |
|---|---|---|---|
| 02:14:07 | GET /.env /.git/config /actuator |
404 | Recon from one IP |
| 02:14:08 | GET /api/v1/openapi.json |
200 | Full route map, handed over |
| 02:14:09 | POST /api/v1/signup |
201 | A fresh account |
| 02:14:11 | GET /api/v1/invoices/10418 … 11203 |
200 | 785 invoices that weren’t theirs |
| 02:16:30 | POST /api/v1/login |
401 | 1,240 attempts across 312 IPs |
| 02:19:44 | PATCH /api/v1/users/me {"role":"admin"} |
200 | Mass assignment |
| 02:21:02 | POST /api/v1/chat "ignore previous…" |
200 | Prompt injection |
| 02:23:15 | POST /api/v1/coupons/redeem |
200 | 64 redemptions, one account |
| 02:24:50 | GET /api/v1/export?limit=100000 |
500 | Stack trace leaked |
Every line is a decade-old technique. An agent just runs them all in a row.
And that’s the version where you have request logs. Without them, this is what you’re at risk for, and you’d have no record it happened.
Five checks that stop most of it
The full checklist has 40 items. These five close the worst gaps in the log above.
1. Scope every object lookup to the caller
Broken object-level authorization is #1 on the OWASP API Security Top 10 because it’s one missing WHERE clause, and agents are built to find it. The agent signs up, fetches its own invoice, sees /invoices/10418, and asks for 10419. Then the next 784. A human gets bored at ten. The agent doesn’t.
app.get('/api/invoices/:id', requireAuth, async (req, res) => {
const invoice = await db.invoice.findFirst({
where: { id: req.params.id, accountId: req.user.accountId }, // ownership, every time
});
if (!invoice) return res.status(404).end();
res.json(toPublicInvoice(invoice)); // allowlisted fields only
});
If the row isn’t theirs, it doesn’t exist. Return 404, not 403, so you don’t confirm it’s there.
2. Rate limit login on the account, not just the IP
Per-IP limits fail against rotating proxies. In the log above, 1,240 login attempts came from 312 IPs, so no single IP looked busy. Key the limit on the targeted account too.
import { rateLimit, ipKeyGenerator } from 'express-rate-limit';
app.post('/api/login', express.json(), rateLimit({
windowMs: 15 * 60_000,
limit: 10,
standardHeaders: 'draft-8',
legacyHeaders: false,
keyGenerator: (req) => `${ipKeyGenerator(req.ip)}:${req.body?.email ?? ''}`,
}), login);
3. Reject fields you didn’t ask for
Mass assignment turns any profile update into a promotion. AI-generated handlers love data: req.body. A strict schema rejects unknown keys before they ever reach the database.
import { z } from 'zod';
const UpdateProfile = z.strictObject({ // unknown keys → 400
name: z.string().trim().min(1).max(80),
timezone: z.string().max(64).optional(),
});
app.patch('/api/users/me', express.json({ limit: '100kb' }), async (req, res) => {
const parsed = UpdateProfile.safeParse(req.body);
if (!parsed.success) return res.status(400).json({ error: 'invalid_body', requestId: req.id });
await db.user.update({ where: { id: req.user.id }, data: parsed.data });
res.status(204).end(); // {"role":"admin"} never got this far
});
4. Fail quietly
A verbose 500 is a free architecture diagram: your ORM, your table names, your file paths. In production, return an error code and a request ID. Log the detail; send the ID. And cap the things that make 500s easy to trigger: body size, page size and export size.
5. Treat your AI feature like the API it is
A chat box or an agent with tools is a new endpoint that takes free text and acts on it. You can’t fully prevent prompt injection. You can make sure an injected model can only do what that user already could:
- Run every tool call with the end user’s permissions, never a service account’s.
- Set per-user token, request and spend budgets. An open chat endpoint is a free model for anyone who finds it, billed to you.
- Require a human click for anything irreversible: refunds, deletes, sends, payments.
The one that unlocks the rest
Alerts, enumeration detection, prompt forensics and incident scope all depend on one thing: knowing what’s hitting your API. If you only do one thing today, start logging every request, with secrets redacted before they’re stored.
Get the full 40-point checklist
The AI-Era API Security Checklist covers all 40 checks across 9 areas, each prioritized and mapped to the OWASP API Security Top 10 and the OWASP Top 10 for LLM Apps. It also includes:
- 5 Node snippets you can paste today
- A 30-day plan for a team of one to twenty
- An AI audit prompt. Paste it into Claude Code, Cursor or Copilot from your repo root, and it audits your app against all 40 items and writes a full report with file-and-line evidence.
Attackers point agents at your API. Point one at your code first.
Sources: Thales/Imperva, 2026 Bad Bot Report; Asia Pacific Defence Reporter on the same Thales report; Veracode, 2025 GenAI Code Security Report; OWASP API Security Top 10 (2023); OWASP Top 10 for LLM Applications (2025). Code samples target express-rate-limit 8 and zod 4 and are starting points, not drop-in security.