The auth middleware mistake AI coders make most often
Par Seaworthy · 30 mai 2026
Photo by Muhammad Zaqy Al Fattah on Unsplash
I've seen this bug in enough codebases now that I've stopped being surprised by it. You ask your AI assistant to add JWT authentication to an Express router, and the generated code looks reasonable at a glance. The authMiddleware function is there. The token validation logic exists. But the route is wide open to the internet, because the middleware got registered in the wrong place.
The mistake is subtle. Middleware in Express needs to be applied before the route it should protect. When an AI generates code that attaches the middleware after the route definition, the check never runs. The route responds to requests before Express ever reaches the authentication logic.
Here's what that looks like:
// Bad: middleware registered after the route
const express = require('express');
const router = express.Router();
const { authMiddleware } = require('./middleware/auth');
router.get('/admin/users', (req, res) => {
// This handler runs before authMiddleware ever sees the request
const users = db.getAllUsers();
res.json(users);
});
router.use(authMiddleware); // Too late: only protects routes defined after this line
That /admin/users endpoint is wide open. Anyone can hit it. authMiddleware will run for routes defined after it in the file, but not for this one.
The fix is simple:
// Fixed: middleware registered before the route
const express = require('express');
const router = express.Router();
const { authMiddleware } = require('./middleware/auth');
router.use(authMiddleware); // Now covers all routes below
router.get('/admin/users', (req, res) => {
const users = db.getAllUsers();
res.json(users);
});
Or, for route-specific protection:
// Also correct: pass middleware as an argument before the handler
router.get('/admin/users', authMiddleware, (req, res) => {
const users = db.getAllUsers();
res.json(users);
});
Why AI tools produce this pattern
The ordering problem makes sense once you think about how language models work. They predict tokens based on patterns in training data, and a lot of Express tutorials add middleware at the end of a file as a finishing touch. The model absorbed that habit. When you ask it to bolt authentication onto an existing route file, it tends to append the middleware call after the routes rather than insert it before them.
This is different from a typical human mistake. A developer who understands Express middleware execution would catch this in a mental walkthrough of the file. But if you're relying on generated code and skipping that walkthrough, it passes unnoticed. The code is syntactically valid, so linting clears. Your editor shows no red squiggles.
The bug also has a way of hiding in tests. If your test suite mounts the router and mocks the middleware, you'll get green tests on a broken endpoint. Most testing setups do this by default. You'd need an integration test that actually runs the middleware chain to expose it.
How often does this actually happen
Often enough that I check for it by default when reviewing AI-generated route files. It's not isolated to one model. The pattern shows up across different AI tools because they all trained on similar codebases and tutorials with the same flawed habits built in. No model is reliably immune.
The problem is worse when you ask a model to modify an existing file rather than generate a fresh one. When building from scratch, the model usually structures things correctly. When inserting into existing code, it has to reason about where the new lines belong relative to what's already there. That's harder, and the ordering slips.
The routes most at risk are admin and internal endpoints, because those get added after the initial public-facing routes were already defined. Someone writes the public routes first, gets it working, then asks the AI to add authentication to the admin section. That's the exact workflow that produces the bug. And those admin routes are precisely where an authentication gap has real consequences.
What to look for in a code review
When you're reading AI-generated Express code, find every router.use(authMiddleware) or app.use(authMiddleware) call and confirm it appears before the routes it's supposed to protect. Don't rely on the file's visual layout. Read the execution order.
For per-route middleware, the argument order matters too:
// Wrong: handler runs first, middleware is never reached
router.get('/admin/data', (req, res) => { /* ... */ }, authMiddleware);
// Correct: middleware runs first
router.get('/admin/data', authMiddleware, (req, res) => { /* ... */ });
If you have a router.use call and then add new routes below it later, the new routes need to stay below it. Route files grow and the ordering drifts as people add endpoints without thinking about where the middleware boundary is.
The failure mode is silent
This is what makes the bug genuinely dangerous. The endpoint works and responses come back normally. Nothing logs an error, nothing fires an alert. You only find out when someone who shouldn't have access uses it, or when you read the code carefully enough to notice.
Auth middleware ordering is one instance of a broader category: code that fails not because it's syntactically wrong but because execution order matters and the model didn't get it right. Most static analysis tools don't catch it. Most code reviews miss it unless the reviewer is specifically looking.
Seaworthy flags this pattern automatically as part of its security checks.
Cet article a été généré par IA et résume des sources publiquement disponibles.
Seaworthy analyse votre dépôt pour détecter les problèmes abordés dans des articles comme celui-ci.
Failles de sécurité, secrets exposés et mauvaises configurations détectés avant le déploiement. Gratuit, aucun compte requis.