Express gives you a router and nothing else, which is the appeal and the problem. Every protection is something you added on purpose.
The middleware baseline
Four things worth understanding rather than copying.
helmet sets a set of security headers. Content Security Policy is the one worth configuring properly rather than leaving at defaults.
CORS with a wildcard. This turned up again and again across those 561 findings, and the cause was the same each time, it was set so a preview would render, and nobody went back to it. Name your origin.
Body size limits. Without one, express.json() accepts whatever it's sent. The default is not unlimited, but it's larger than most APIs need.
Rate limiting on auth routes. Login, password reset and OTP endpoints without throttling were another recurring finding. Stricter limits there than on the rest of the API.
Middleware order matters
Express runs middleware in registration order, and mistakes here are silent.
Anything registered before the auth middleware is public. This is easy to get wrong during a refactor and produces no error.
The error handler
The default handler returns stack traces in development and it's common for that to survive into production.
Log the detail server-side, return nothing useful to the caller. Also set NODE_ENV=production. Several defaults depend on it.
What middleware can't do
Everything above is global. The most consequential bug in an Express API isn't.
requireAuth confirms someone is logged in. Nothing confirms they own this order. That's broken object-level authorisation, and it was the most consequential thing we found across the AI-generated apps we scanned.
There's no middleware for it, because the check depends on what the route is doing. It has to be in the query:
Every route that reads a record needs its own version of this, and getting it right on forty routes and missing the forty-first is the same outcome as never doing it. That's a coverage problem rather than a knowledge problem.