Profiles·Public

cors

semver>=2.0.0postconditions4functions1last verified2026-04-18coverage score100%

Postconditions — what we check

  • cors · wildcard-origin-no-protection
    error
    Whencors() is called with no arguments, or cors({ origin: '*' }) is used
    ReturnsMiddleware that sets Access-Control-Allow-Origin: * on all responses, allowing any origin
    Required handlingCaller MUST NOT use cors() with no arguments or origin: '*' for any API that handles authenticated requests or sensitive data. Use an explicit allowlist or a validation function. cors() with no args is equivalent to cors({ origin: '*' }) — it allows all browser origins unconditionally. The lib/index.js defaults object confirms: origin defaults to '*'.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2][3]
  • cors · origin-reflection-no-validation
    error
    Whencors({ origin: true }) is used
    ReturnsMiddleware that reflects the request's Origin header back in Access-Control-Allow-Origin without any validation
    Required handlingCaller MUST NOT use origin: true in production. This is functionally equivalent to a wildcard — any website can make cross-origin requests. Use an allowlist or a callback function that validates the origin before reflecting it. Confirmed: lib/index.js isOriginAllowed() → return !!allowedOrigin when allowedOrigin is boolean true.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][4]
  • cors · credentials-with-wildcard-invalid
    error
    Whencors() is configured with both credentials: true and origin: '*'
    ReturnsMiddleware that sends both Access-Control-Allow-Credentials: true and Access-Control-Allow-Origin: *, which is rejected by all browsers per the CORS specification
    Required handlingCaller MUST NOT combine credentials: true with origin: '*'. This configuration is invalid per the CORS spec and browsers will block all credentialed requests. Use an explicit origin string or validated callback with credentials: true. The server sends both headers without error — the rejection happens silently in the browser.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5][6]
  • cors · delegate-error-propagation
    warning
    Whencors() is called with a CorsOptionsDelegate or a custom origin function, and that callback passes an error as the first argument (or throws synchronously), but the Express error handler is not set up to handle CORS-layer errors. Common triggers: - Database lookup for dynamic origin allowlist fails (network error, query error) - The origin validation function throws synchronously - An async callback is used but errors are not caught before passing to the callback Note: the cors middleware does NOT accept async delegate functions directly (it uses the Node callback pattern). If you wrap an async call, you must catch errors: cors((req, callback) => { db.getAllowedOrigins().then(origins => callback(null, { origin: origins })) .catch(err => callback(err)); // ← REQUIRED: must call callback(err) })
    ThrowsThe error passed to callback(err) is forwarded to Express's next(err). This triggers Express's error-handling middleware (app.use((err, req, res, next) => ...)). If no error middleware is configured, Express sends a 500 Internal Server Error with the full error stack trace — potentially exposing internal details (database errors, file paths, etc.) to the client.
    Required handlingWhen using a CorsOptionsDelegate with async operations: 1. ALWAYS catch errors before calling callback(): cors((req, callback) => { db.getAllowedOrigins() .then(origins => callback(null, { origin: origins })) .catch(err => { console.error('CORS origin lookup failed:', err); callback(err); // passes to Express error handler }); }) 2. ALWAYS have an Express error handler that sanitizes the response: app.use((err, req, res, next) => { // Don't leak internal error details res.status(500).json({ error: 'Internal server error' }); }); 3. Consider a fallback origin (deny all) on error: cors((req, callback) => { db.getAllowedOrigins() .then(origins => callback(null, { origin: origins })) .catch(() => callback(null, { origin: false })); // deny on error }); The callback must ALWAYS be called exactly once. Forgetting to call it on error leaves the request hanging indefinitely (no response sent, connection stays open).
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2][1]

Sources

Every postcondition cites at least one of these. Numbered to match the footnotes above.

  1. [1]raw.githubusercontent.com/expressjs/corshttps://raw.githubusercontent.com/expressjs/cors/master/README.md
  2. [2]github.com/expressjs/corshttps://github.com/expressjs/cors/blob/master/lib/index.js
  3. [3]snyk.io/blog/security-implications-cors-node-jshttps://snyk.io/blog/security-implications-cors-node-js/
  4. [4]acunetix.com/vulnerabilities/scahttps://www.acunetix.com/vulnerabilities/sca/cve-2023-49803-vulnerability-in-npm-package-koa-cors/
  5. [5]github.com/expressjs/corshttps://github.com/expressjs/cors/issues/283
  6. [6]github.com/gofiber/fiberhttps://github.com/gofiber/fiber/security/advisories/GHSA-fmg4-x8pw-hjhg
Need a different package?
Request a profile