Your Server Shares Data With Any Website on the Internet

Your application is configured to allow any website in the world to read responses from your server. Think of it like leaving your office filing cabinet unlocked — anyone who walks past can look inside. For pages that are genuinely public (like a marketing site), this is fine. For pages that return user data, account info, or internal details, it's a gap worth closing.

Business Impact And Actions

medium urgency

Business Impact

If any of your API endpoints return data that isn't meant for the general public — even without requiring a login — that data can be read by scripts running on other websites. This could expose user details, internal IDs, or configuration data. It also increases your exposure during compliance reviews (SOC 2, ISO 27001) where overly permissive data-sharing policies are flagged.

What To Do

  1. Ask your developer to review which parts of your application have this setting and whether those pages return any non-public data.
  2. For any endpoint that returns user-specific or internal data, ask your developer to restrict access to only your own domain(s) — this is a configuration change, typically under an hour.
  3. If you run a public API intentionally open to third-party developers, this setting may be appropriate — confirm this is a deliberate choice, not an accidental one.
  4. Add this to your next security review checklist to ensure new endpoints don't inherit an overly open default.

CORS Wildcard Origin (Access-Control-Allow-Origin: *) Exposes Unauthenticated Endpoints

medium severity CVSS 4.3–6.5

Vulnerability Explanation

The server responds with `Access-Control-Allow-Origin: *`, which instructs browsers to permit any website to read the response body via cross-origin JavaScript (fetch/XHR). While browsers block credentials (cookies, HTTP auth) from being sent alongside wildcard CORS responses — preventing direct session-riding attacks — any unauthenticated endpoint returning sensitive data is fully readable by scripts on attacker-controlled pages. This includes endpoints protected only by network controls (IP allowlists, VPN assumptions) rather than application-layer authentication, internal service discovery endpoints, and any data that is non-public but served without a login check.

Root Cause

Wildcard CORS is commonly set as a development convenience or as a blanket default for APIs intended to be public. The setting is then inherited by all routes — including those that were never meant to be publicly accessible. Frameworks like Express (cors({ origin: '*' })), Nginx (add_header Access-Control-Allow-Origin "*"), and Spring Boot often make this a single-line global config, making it easy to apply too broadly.

Technical Impact

An attacker can host a malicious web page that silently fetches unauthenticated API responses from the target application and exfiltrates the data to their own server. Realistic targets include: public-but-sensitive endpoints (e.g., /api/config, /api/version, /health), endpoints behind IP-based access controls that a victim's browser can reach, and any route that leaks internal structure, user counts, or enumerable IDs. If the wildcard is ever paired with `Access-Control-Allow-Credentials: true` (a misconfiguration browsers reject, but some server-side proxies do not), the impact escalates to full authenticated data exfiltration.

Severity Justification

Credentials cannot be sent with wildcard CORS responses per the browser specification, limiting direct session-riding. However, unauthenticated endpoints returning sensitive data are fully exposed. Risk is context-dependent: low for genuinely public APIs, medium-high for applications with sensitive unauthenticated routes or IP-only access controls.

Affected Components

  • Any server returning Access-Control-Allow-Origin: * — all versions

Remediation Steps

  1. Audit which endpoints return `Access-Control-Allow-Origin: *` — use `curl -I -H 'Origin: https://evil.com' https://yourapp.com/api/endpoint` to check individual routes.
  2. Replace the wildcard with an explicit allowlist of trusted origins. Validate the incoming `Origin` header against this list server-side and reflect only matched origins.
  3. For APIs that must support multiple legitimate origins, maintain an in-memory or config-file allowlist and dynamically reflect the matched origin (with `Vary: Origin` set to prevent cache poisoning).
  4. Ensure `Access-Control-Allow-Credentials: true` is NEVER combined with a wildcard or dynamic reflection without strict origin validation — this combination is critically dangerous.
  5. If the endpoint is genuinely a public API with no sensitive data, document the decision explicitly so future developers don't assume the wildcard is a mistake.

Verification Steps

  1. Run: `curl -s -I -H 'Origin: https://evil-test.com' https://yourapp.com/api/` and confirm the response does NOT contain `Access-Control-Allow-Origin: *` or `Access-Control-Allow-Origin: https://evil-test.com`.
  2. Run the same curl with a legitimate origin (e.g., your own domain) and confirm it IS reflected correctly.
  3. Check the response includes `Vary: Origin` when using dynamic reflection, to prevent CDN/proxy cache poisoning.
  4. Use the CORS tester at https://www.test-cors.org or browser DevTools Network tab to confirm cross-origin requests from untrusted origins are blocked.

Code Examples (javascript)

Vulnerable
// Express.js — wildcard applied globally
const cors = require('cors');
app.use(cors()); // defaults to Access-Control-Allow-Origin: *

// Or explicitly:
app.use(cors({ origin: '*' }));
Fixed
// Express.js — explicit allowlist with dynamic reflection
const cors = require('cors');

const ALLOWED_ORIGINS = [
  'https://app.yourcompany.com',
  'https://www.yourcompany.com'
];

app.use(cors({
  origin: function (origin, callback) {
    // Allow requests with no origin (e.g. server-to-server, curl)
    if (!origin) return callback(null, true);
    if (ALLOWED_ORIGINS.includes(origin)) {
      return callback(null, true);
    }
    return callback(new Error('CORS policy: origin not allowed'));
  },
  credentials: true // safe — only matched origins are reflected
}));

// Nginx equivalent:
# map $http_origin $cors_origin {
#   default "";
#   "https://app.yourcompany.com" $http_origin;
#   "https://www.yourcompany.com" $http_origin;
# }
# add_header Access-Control-Allow-Origin $cors_origin always;
# add_header Vary Origin always;

Best Practices

  • Never use `Access-Control-Allow-Origin: *` on any endpoint that returns non-public data, even if that endpoint currently has no authentication.
  • Always set `Vary: Origin` when dynamically reflecting origins to prevent shared caches from serving the wrong CORS header to different clients.
  • Treat CORS as a complement to — not a replacement for — server-side authentication. Enforce auth on every sensitive route independently.
  • Avoid wildcards in internal or intranet-facing applications; network location alone is not a reliable access control boundary.

Found this in your infrastructure?

VulWall scans for this and dozens of other issues automatically.

Scan Your Domain Free