← All posts
CORSAPI securityfix CORS misconfigurationcross-originweb security

Fix CORS Misconfiguration: Secure Your API in 5 Steps

O

OverMCP Team

TL;DR: How to Fix CORS Misconfiguration in an API

CORS misconfiguration happens when your API allows requests from origins you don't control, or blocks legitimate ones. To fix it: (1) restrict Access-Control-Allow-Origin to specific trusted domains, not *, (2) validate the Origin header server-side, (3) avoid reflecting the origin without validation, (4) tighten Access-Control-Allow-Methods and Access-Control-Allow-Headers, and (5) never expose sensitive data via Access-Control-Expose-Headers. Use a library like cors for Node.js, or configure your framework's CORS middleware correctly.

What Is CORS and Why Misconfigurations Are Dangerous

CORS (Cross-Origin Resource Sharing) is a browser security mechanism that controls which websites can access your API. A misconfiguration—like setting Access-Control-Allow-Origin: * or blindly reflecting the Origin header—can let any malicious site read your API responses, leading to data theft, account takeover, or CSRF-style attacks.

The Most Common CORS Misconfigurations

  • Wildcard origin (``)** – Allows any website to make cross-origin requests.
  • Reflective origin – Copies the Origin header into the response without validation.
  • Overly permissive methods – Exposing PUT, DELETE, or PATCH when only GET is needed.
  • Exposing sensitive headers – Using Access-Control-Expose-Headers with Authorization or custom tokens unnecessarily.
  • Allowing credentials with wildcard – Setting Access-Control-Allow-Credentials: true alongside * causes browsers to reject the request, but also exposes potential for attack if misconfigured.
  • Step-by-Step: How to Fix CORS Misconfiguration

    Step 1: Restrict Allowed Origins

    Never use *. Instead, whitelist your frontend domains.

    #### Node.js (Express) with cors package:

    const cors = require('cors');
    const allowedOrigins = ['https://myapp.com', 'https://admin.myapp.com'];
    const corsOptions = {
      origin: function (origin, callback) {
        if (!origin || allowedOrigins.indexOf(origin) !== -1) {
          callback(null, true);
        } else {
          callback(new Error('Not allowed by CORS'));
        }
      },
      credentials: true
    };
    app.use(cors(corsOptions));

    #### Python (Flask):

    from flask import Flask, request
    from flask_cors import CORS
    app = Flask(__name__)
    CORS(app, origins=['https://myapp.com', 'https://admin.myapp.com'], supports_credentials=True)

    Step 2: Validate Origin Server-Side

    If your framework doesn't handle CORS middleware, manually check the Origin header:

    app.use((req, res, next) => {
      const origin = req.headers.origin;
      if (allowedOrigins.includes(origin)) {
        res.setHeader('Access-Control-Allow-Origin', origin);
      }
      next();
    });

    Step 3: Tighten Allowed Methods and Headers

    Only allow methods your API actually uses:

    res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');

    Step 4: Limit Exposed Headers

    Remove any headers you don't need the client to read:

    res.setHeader('Access-Control-Expose-Headers', 'X-Request-Id'); // not 'Authorization'

    Step 5: Handle Preflight Requests Correctly

    Preflight OPTIONS requests should respond quickly with the CORS headers and a 204 status:

    app.options('*', (req, res) => {
      res.setHeader('Access-Control-Allow-Origin', 'https://myapp.com');
      res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
      res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
      res.sendStatus(204);
    });

    Real-World Example: Fixing a Reflected Origin Vulnerability

    Imagine your API echoes the Origin header like this:

    res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
    res.setHeader('Access-Control-Allow-Credentials', 'true');

    An attacker can create a malicious page at https://evil.com that makes authenticated requests to your API. The browser sees Access-Control-Allow-Origin: https://evil.com and allows reading the response, leaking user data.

    Fix: Validate the origin against a whitelist, as shown in Step 2.

    Testing Your CORS Configuration

    Use tools like curl or browser dev tools to verify:

    curl -H "Origin: https://evil.com" -I https://api.myapp.com/data

    Check that the response doesn't include Access-Control-Allow-Origin: https://evil.com. Also test legitimate origins.

    How OverMCP Can Help

    OverMCP (overmcp.com) automatically scans your vibe-coded apps for common security issues like CORS misconfigurations. It checks your API endpoints and flags overly permissive CORS settings, helping you catch vulnerabilities before deployment.

    Conclusion

    Fixing CORS misconfigurations is essential for securing your API. By restricting origins, validating headers, and limiting methods, you can prevent data leaks and cross-origin attacks. Always test your configuration and use automated tools to stay safe.

    FAQ

    What happens if I don't fix CORS misconfiguration?

    Attackers can make cross-origin requests from any domain, potentially stealing user data or performing actions on behalf of authenticated users.

    Can I use `Access-Control-Allow-Origin: *` with credentials?

    No. Browsers block requests with credentials if the origin is *. You must specify exact origins and set Access-Control-Allow-Credentials: true.

    How do I fix CORS for multiple subdomains?

    Use a dynamic check: allow origins that match your domain pattern (e.g., *.myapp.com). Some frameworks support regex patterns, or you can implement custom logic.

    Is your app secure?

    Free scan in 30 seconds. No signup needed.

    Scan My App Free