Fix Insecure API Routes in AI-Built Apps: A Step-by-Step Guide
OverMCP Team
Quick answer
Insecure API routes in AI-built apps often lack authentication checks, have no input validation, and expose sensitive data. Fix them by adding middleware for auth, validating all inputs, and restricting HTTP methods. Use a security scanner to catch these issues before deployment.
What to check first
Before diving into fixes, run this checklist on every API route:
requireAuth)zod or joi?If most boxes are unchecked, your API routes are likely insecure. AI coding tools like Cursor or Bolt.new often generate minimal routes that skip these checks.
Step-by-step fix
1. Add authentication middleware
Most AI-generated routes miss authentication. Add a middleware that verifies tokens or session cookies.
// middleware/auth.js
import jwt from 'jsonwebtoken';
export function requireAuth(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Unauthorized' });
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (err) {
return res.status(401).json({ error: 'Invalid token' });
}
}2. Validate all inputs
AI code often trusts user input. Use a schema validator to enforce types and constraints.
import { z } from 'zod';
const createUserSchema = z.object({
email: z.string().email(),
name: z.string().min(2).max(50),
age: z.number().int().positive().optional(),
});
// In your route handler
const parsed = createUserSchema.safeParse(req.body);
if (!parsed.success) {
return res.status(400).json({ error: parsed.error.flatten() });
}3. Restrict HTTP methods
Ensure routes only accept expected methods. This prevents unintended operations.
// In your route definition (Next.js App Router example)
export async function POST(req) {
// Only POST allowed
}
export async function GET(req) {
return new Response('Method not allowed', { status: 405 });
}For Express-like frameworks, use method check:
app.post('/api/users', (req, res) => { /* ... */ });
app.all('/api/users', (req, res) => res.status(405).end());4. Sanitize error messages
Don't leak stack traces or internal details. Always return generic errors.
try {
// risky operation
} catch (err) {
console.error(err); // log internally
res.status(500).json({ error: 'Internal server error' });
}5. Filter sensitive data from responses
Use a serialization library or manual mapping to exclude fields like passwords.
function sanitizeUser(user) {
const { password, apiKey, ...safeUser } = user;
return safeUser;
}6. Add rate limiting
Prevent abuse with a simple rate limiter.
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests, please try again later.'
});
app.use('/api/', limiter);7. Configure CORS properly
Don't use Access-Control-Allow-Origin: * in production. Restrict to your domain.
import cors from 'cors';
app.use(cors({
origin: 'https://yourapp.com',
methods: ['GET', 'POST'],
credentials: true,
}));8. Scan for leaked secrets
Use a secret leak scanner to find hardcoded API keys or tokens in your codebase before deploying.
Common mistakes
How to prevent these issues in future AI coding sessions
FAQ
What is an insecure API route?
An API route that lacks authentication, input validation, or proper error handling, making it vulnerable to unauthorized access, injection, or data leaks.
How do I know if my API routes are insecure?
Run a security scan or manually check for missing auth, validation, and exposed secrets. Tools like OverMCP's security headers checker can help.
Can AI coding tools generate secure API routes?
Yes, if you prompt them correctly. Always include security requirements in your prompts and review the generated code for common mistakes.