Framework audits/Express

Express.js Security Audit

What should an Express security audit check?

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.

Frequently asked questions

Is Express secure by default?

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.

Related reading