Express is deliberately minimal, so an audit is mostly about what is missing rather than what is wrong. The recurring findings are absent security headers, request values used directly in queries and shell commands, error handlers returning stack traces to clients, and a permissive cross-origin policy added to unblock a frontend.
Unlike a batteries-included framework, Express provides no defaults to step around — every protection is something a developer chose to add, which means an audit is an inventory of decisions never made.
Where Express codebases actually break
These are patterns we look for in code produced this way — not flaws in Express itself. Each names the check that finds it.
Request values flowing straight into database queries
Express hands route parameters, query strings and bodies to the handler as plain values with no validation layer in between. Where those values reach a query built by string concatenation — which is common in code written quickly against a driver rather than an ORM — the endpoint is injectable.
Detected by: SQL string concatenation
Error handlers that return the stack trace
The default error behaviour in development returns the stack, and a custom handler written to aid debugging often does the same. In production that response reveals file paths, dependency versions and internal structure to anyone who can provoke an error, which is reconnaissance handed over on request.
Detected by: console.log with sensitive data
Cross-origin policy opened to unblock the frontend
A frontend blocked by CORS is fixed in seconds by allowing every origin, and that change is rarely narrowed afterwards. Combined with cookie-based sessions it lets any site issue authenticated requests on a visitor's behalf.
Detected by: Unvalidated request input
User input reaching a shell command
Endpoints that process files or invoke command-line tools build shell strings at runtime from whatever the request supplied. Where any component of that string — a filename, a format flag, a path — comes from the caller, the endpoint quietly offers command execution rather than the file conversion it appears to offer.
Detected by: exec/spawn with user input risk
Auditing a Express codebase: the short list
Confirm a security-headers middleware is installed and actually mounted before the routes
Trace every route parameter and body field that reaches a query, and confirm parameterisation
Trigger an error in production and read exactly what the response body contains
Check the cross-origin configuration names specific origins rather than allowing all
Confirm a body size limit exists — the default permits large payloads that are trivially abusable
Scan your Express codebase
Every check named above runs automatically. Free on public repositories, no signup, results in under three minutes — with the file and line for each finding.
Express makes almost no security decisions for you, which is its design intent. There are few insecure defaults to fix; there are many protections that simply do not exist until someone adds them, so an Express audit is an inventory of what was never installed.
What middleware should every Express app have?
At minimum: security headers, a request body size limit, an explicit cross-origin policy naming real origins, and an error handler that returns a generic message to the client while logging the detail server-side. Rate limiting matters as soon as any endpoint is expensive or authentication-adjacent.
How do I check an Express API for injection?
Follow the request values. Every route parameter, query string entry and body field is untrusted input; find where each one reaches a database driver or a shell invocation, and confirm it is passed as a parameter rather than concatenated into a string.