Skip to content
GDPR compliant. Hosted in DE.
14-day free trial →
Security MonitoringCORS HeadersPreflight Check
Security 12 min read 25 Jun 2026

Detect and Monitor CORS Misconfigurations

An overly loose CORS response opens your API to foreign sites. Learn to detect CORS misconfigurations, check preflight headers and protect your data.

X

XICTRAQ Team

XICTRAQ

SecurityCORSHeaderAPIMonitoring
27.5%
of CORS-configured domains showed insecure settings (Chen et al., USENIX 2018)
4.88m USD
average cost of a data breach in 2024 (IBM Cost of a Data Breach 2024)
77%
of basic web app attacks use stolen credentials (Verizon DBIR 2024)
Check CORS headers: preflight and responseBrowser sends a cross-origin request to the API - the response headers decide the riskBrowserOrigin: evil.examplefetch(api, {credentials:'include' })OPTIONS PreflightResponse-HeaderAPI endpoint /api/v1/meAccess-Control-Allow-Methods:GET, POSTAccess-Control-Allow-Origin:AllowlistAccess-Control-Allow-Credentials:trueVary:OriginXICTRAQ header checkNo wildcard with credentialsOrigin not reflected uncheckedVary: Origin setSecure configurationpermittedAllow-Origin: https://app.customer.comexact allowlistCredentials only with real origincouplednull origin is rejectedblockedMisconfigurationexploitableAllow-Origin reflects any originReflectionWildcard plus credentials trueData leaknull origin treated as trustedbypassable!Alert: endpoint reflects any origin with credentials since deploy v204Notification via email, Slack, Discord or Telegram - before data is exposed27.5% of CORS-configured domains showed insecure settings (Chen et al., USENIX 2018) - XICTRAQ monitoring
Cross-Origin Resource Sharing (CORS) governs which foreign web applications may access your API - and that is exactly what makes a CORS misconfiguration one of the most underestimated security risks on the web. A single overly permissive line in the server response can let any website on the internet send authenticated requests to your API and read the responses. A large empirical study presented at the USENIX Security Symposium found that 27.5% of all CORS-configured domains had insecure settings (Chen et al., USENIX 2018). Because these headers can change with every deploy and usually stay invisible in the browser, they need continuous monitoring. This guide explains how CORS works, which misconfigurations occur most often and how security header monitoring surfaces them before they turn into a data leak.

What CORS Is and Why It Exists

Browsers enforce the same-origin policy: by default, scripts from one origin (origin = scheme, host and port) may not read responses from another origin. This rule prevents a malicious page from silently siphoning data from another domain where you are logged in. CORS is the mechanism standardised by the W3C and WHATWG that lets a server relax this rule in a controlled way - it tells the browser, via dedicated response headers, which foreign origins may access its resources (MDN Web Docs).

The central header is Access-Control-Allow-Origin. If it names a concrete origin such as https://app.kunde.de, the browser grants read access to that - and only that - site. If it contains the wildcard *, access is open to any origin. This is complemented by Access-Control-Allow-Credentials, which decides whether cookies and authentication data may be sent, plus Access-Control-Allow-Methods and Access-Control-Allow-Headers for the permitted HTTP methods and headers. The interplay of these headers determines security - and this is exactly where the typical mistakes arise.

An important distinction: CORS is not server-side access control. The mechanism only instructs the browser to block or release a response for foreign JavaScript. An attacker accessing the API directly - for example via a script outside the browser - is not stopped by CORS. The protection only applies in the browser context of a victim whose logged-in session is to be abused. Treating CORS as a substitute for authentication or authorisation builds a false sense of security. This confusion is one of the most common causes of risky configurations.

Preflight Requests: the Invisible Second Request

Not every cross-origin request reaches the server directly. The browser distinguishes between simple requests and those that trigger a preflight request. Simple requests use the GET, HEAD or POST methods with a small set of allowed headers - they go out without a prior check. As soon as another method such as PUT, PATCH or DELETE or a custom header like Authorization comes into play, however, the browser first sends an OPTIONS request ahead of it (MDN Web Docs).

This preflight request asks the server: may the intended method, with these headers, come from this origin? The server answers with Access-Control-Allow-Methods, Access-Control-Allow-Headers and the permitted origin. Only if the answer fits does the browser send the actual request. For monitoring, this two-stage nature is essential: a misconfiguration can hide either in the preflight response (for example overly broad allowed methods) or in the final response (for example a reflected origin). A check that only looks at the GET path misses half the picture.

Why Preflight Headers Are Often Overlooked

The OPTIONS preflight response appears in no normal page view and is not captured by simple availability checks. It is only visible if a tool deliberately simulates a cross-origin method with custom headers and logs the response headers. That is exactly why overly permissive preflight responses often go undetected until they are actively tested.

A practical side effect of the preflight mechanism concerns caching. Via the Access-Control-Max-Age header the server can define how long the browser reuses a preflight response before asking again. If this value is set very high, stale or accidentally overly permissive preflight responses can remain in the browser cache for longer - a fix on the server then does not take effect immediately for all visitors. For monitoring this means: the Max-Age value, too, is part of the picture that a thorough header check captures, because it co-determines how quickly a change is reflected in real behaviour.

The Most Common CORS Misconfigurations

Most dangerous CORS configurations arise from the attempt to quickly clear a browser error. Developers see a blocked request, read the origin from the Origin header and reflect it back unchecked - the error disappears, the gap remains (PortSwigger Web Security Academy). The overview below ranks the typical patterns by their risk.

ConfigurationBehaviourRisk
Origin reflected uncheckedServer copies any Origin header into Allow-OriginHigh - any site reads credentialed responses
Wildcard with credentialsAllow-Origin: * together with Credentials: trueHigh - barred by the spec, but bypassed via reflection
null origin trustedAllow-Origin: null is acceptedMedium to high - exploitable via a sandboxed iframe
Overly broad suffix matchingkunde.de also matches evil-kunde.deHigh - attacker registers a matching domain
All subdomains trustedevery *.kunde.de counts as allowedMedium - one taken-over subdomain is enough
Wildcard without credentialsAllow-Origin: * for purely public dataLow - usually acceptable

Particularly insidious is the unchecked reflected origin combined with Access-Control-Allow-Credentials: true. This combination is functionally equivalent to a wildcard for credentialed requests: any website on the internet can then make requests with the victim's cookies and read the responses (PortSwigger Web Security Academy). The CORS standard does forbid the literal combination of * plus credentials - but reflecting the concrete origin bypasses this prohibition entirely. On top of that, the Vary: Origin header is often missing in such cases, which can lead to faulty caching of the permissive response.

The Most Dangerous Quick Fix

Reflecting the Origin header back unchecked is by far the riskiest widespread practice - it usually arises as a supposed bug fix against browser error messages. The correct path is consistently an explicit allowlist of trusted origins, not a dynamic reflection. After every deploy that touches the API layer, this point should be checked first.

Another frequently underestimated source of errors is matching the origin by string comparison instead of by exact validation. If a check only verifies whether the origin contains the own domain as a substring, then https://app.kunde.de.attacker.example may be treated as permitted - the trusted name is contained in it, yet the actual origin is foreign. Equally risky is overly generous suffix matching, where a prefix such as evil-kunde.de wrongly passes as belonging to the own brand. Such logic errors mostly arise in hand-written origin checks and can only be exposed from the outside through targeted probe requests with manipulated origins.

What a CORS Gap Really Means in Terms of Risk

An exploitable CORS misconfiguration lets an attacker read data from your API in the name of a logged-in victim. If the victim visits a crafted page, its JavaScript can send a credentialed request to your application and - thanks to the overly loose headers - read the response: profile data, tokens, internal information. CORS flaws therefore belong to the security misconfiguration category, which is listed as its own risk in the OWASP Top 10 (OWASP). If state-changing methods are open, the same path can also be used to write to the application.

The financial consequences of a resulting data leak are considerable. The average cost of a data breach reached USD 4.88 million worldwide in 2024 - the highest figure since the survey began and a 10 percent increase over the previous year (IBM Cost of a Data Breach 2024). At the same time, according to the Verizon report, 77 percent of basic web application attacks involved stolen credentials (Verizon DBIR 2024) - and it is exactly such credentials and session tokens that can be read out via a CORS gap. A misconfigured CORS response shifts the attack surface into the user's browser, where classic server-side protections do not apply.

From Deploy to Attack Surface

A single build that changes an API's CORS handling can quietly open a confidential interface to the entire web. Because the headers are invisible during normal page operation, this often only surfaces when a security test or an incident brings it to light. Continuous header monitoring shortens this window from weeks to hours.

On top of that comes the sheer prevalence of the problem: in the large-scale study mentioned, tens of thousands of domains trusted all of their subdomains wholesale, so taking over a single forgotten subdomain was enough to exploit the CORS permission (Chen et al., USENIX 2018). This pattern shows that CORS security is closely intertwined with monitoring the entire subdomain and DNS landscape - an overlooked or hijacked subdomain becomes a direct entry point through an overly broad CORS rule.

Checking CORS Headers Correctly

A robust check simulates the behaviour of a real browser: it sends a request with a foreign, deliberately untrusted Origin header and observes what the server returns in the response headers. Does it reflect the foreign origin? Does it set Allow-Credentials: true at the same time? Does it accept a null origin? These are exactly the cases that separate a harmless from an exploitable configuration.

Example: CORS header diff after deploy v204
Probe request:
  Origin: https://evil.example

Response before deploy v204 (target):
  Access-Control-Allow-Origin: https://app.kunde.de
  Access-Control-Allow-Credentials: true
  Vary: Origin
  => foreign origin rejected   ok

Response after deploy v204 (observed):
+ Access-Control-Allow-Origin: https://evil.example
+ Access-Control-Allow-Credentials: true
- Vary: Origin   (missing)
  => foreign origin reflected   VIOLATION

=> Drift detected: endpoint reflects any origin

It is crucial that the check covers several endpoints and both request stages - the preflight response as well as the final response. XICTRAQ security monitoring regularly evaluates the security-relevant response headers of a page, classifies the CORS configuration and compares the current state against a last-known clean baseline. This way a new, overly permissive permission becomes visible as a deviation instead of getting lost in the noise.

  • Foreign probe origin - the check sends a deliberately untrusted origin and observes the server's reaction
  • Reflection detection - whether the foreign origin returns unchecked in Allow-Origin is explicitly verified
  • Credentials coupling - the risky combination of reflected origin and Allow-Credentials: true is highlighted
  • null origin test - it is checked whether a null origin is wrongly treated as trusted
  • Baseline diff - the current set of headers is compared against the last released state, so that only real changes raise an alert

Setting Up a Clean CORS Configuration

A robust CORS configuration follows a few clear principles. First comes the principle of minimal permission: only what is actually needed is allowed - a concrete, short list of trusted origins instead of a wildcard. Every origin on that list should have a comprehensible reason. If the list grows over time, a regular review of whether each entry is still needed pays off, because every additional allowed origin enlarges the attack surface.

  1. Exact allowlist instead of reflection - allowed origins are checked against a fixed list and only returned on an exact match, instead of copying the incoming origin unchecked
  2. Use credentials sparingly - Access-Control-Allow-Credentials: true is only set where authenticated cross-origin access is genuinely required, and consistently combined with an exact origin
  3. Reject the null origin - the value null is not treated as trusted, since it can be produced via sandbox constructs
  4. Set Vary: Origin - as soon as the response varies by origin, this header signals caches to include the origin in the cache key
  5. Keep preflight tight - permitted methods and headers are limited to what the application actually uses

These principles are not a one-off project but a state that should be reconfirmed after every change to the API layer. This is exactly where continuous monitoring comes in: it checks not whether the configuration was once correct, but whether it has stayed that way. A configuration that is clean today may already deviate after the next framework update or middleware change - and without ongoing observation, this deviation stays hidden.

What XICTRAQ Monitors Around CORS and Headers

CORS is one building block of a broader security header picture. An isolated check falls short - only together with the remaining protective headers and ongoing availability checks does a robust picture emerge. XICTRAQ bundles these aspects into continuous monitoring.

CORS header analysis

Classification of Allow-Origin, Allow-Credentials and permitted methods, including detection of reflected and overly broad permissions.

Preflight check

The OPTIONS response is checked too, so that overly permissive Allow-Methods and Allow-Headers are not overlooked.

Baseline and drift

Any change to the CORS headers compared with the released state is detected as a deviation - ideal after every deploy.

Alerting on deviation

A new, overly permissive permission triggers a notification via email, Slack, Discord or Telegram.

This CORS check fits into a larger security header monitoring effort that also covers transport and browser protection mechanisms. Robust protection includes, for example, hardening the TLS cipher suites at the transport layer as well as monitoring the remaining security headers. CORS alone does not protect - it is one link in a chain whose weakest element determines the overall level.

As with other invisible frontend problems, the value lies in early detection: just as monitoring JavaScript errors in the frontend surfaces problems that stay hidden during normal page operation, header monitoring turns a silently created CORS gap into an alertable signal. In both cases the rule holds: what is not measured only becomes apparent when it is too late.

The practical benefit lies in the time factor. Without monitoring, a CORS misconfiguration is typically only discovered during a penetration test, a report or an incident - often weeks or months after the triggering deploy. With continuous checking, the same deviation typically becomes visible within hours, usually before it could be actively exploited. This shortening of the time window is the real protection that ongoing monitoring provides.

It helps to anchor CORS maintenance organisationally. Keeping a short, curated list of the foreign origins actually needed lets you weigh each new permission deliberately against that list instead of adding it reactively in the build. If a planned release adds a new, correctly restricted origin, the baseline should then be deliberately re-released - that way monitoring only alerts on real, unintended deviations and not on every planned change. This separation between intended and unintended change is the core of robust header monitoring.

Sources and Studies

This article draws on data and standards from: Chen, Jiang, Duan, Wan, Chen, Paxson and Yang - We Still Don't Have Secure Cross-Domain Requests: an Empirical Study of CORS (27th USENIX Security Symposium 2018, 27.5% insecure CORS-configured domains, wholesale subdomain trust), MDN Web Docs (CORS fundamentals, preflight requests, Access-Control headers, simple requests), W3C / WHATWG Fetch Standard (CORS protocol), OWASP (security misconfiguration in the OWASP Top 10), PortSwigger Web Security Academy (origin reflection, credentials combination, null origin), IBM Cost of a Data Breach 2024 (average cost USD 4.88 million), Verizon Data Breach Investigations Report 2024 (77 percent stolen credentials in basic web app attacks).

Frequently Asked Questions About CORS Misconfigurations

What exactly is a CORS misconfiguration?
It refers to an overly loose setting of the cross-origin response headers that gives foreign web applications more access to an API than intended. Typical examples are reflecting the request origin back unchecked or a wildcard together with permitted credentials. As a rule, this enables an attacker to read data in the name of a logged-in victim.
Is Access-Control-Allow-Origin: * invariably a security risk?
Not necessarily. For purely public, non-credentialed resources a wildcard can be acceptable. It typically becomes critical only when credentials are allowed at the same time or the origin is reflected unchecked. The assessment depends on the individual case and the sensitivity of the data.
Does CORS protect my API from unauthorised access?
CORS is not server-side access control but an instruction to the browser. An attacker accessing the interface directly outside a browser is not stopped by it. Authentication and authorisation must still happen on the server side - CORS complements them but does not replace them.
Why is a one-off security test not enough?
A one-off test is a snapshot and can be outdated by the next code change. Because CORS headers can flip unnoticed with every deploy of the API layer, continuous monitoring is usually more sensible. It compares the current state with a released baseline and reports only real deviations.
How do you tell whether a server reflects every origin?
Most reliably by sending a request with a deliberately foreign Origin header and checking whether exactly that origin returns in the response. If the foreign value appears in Access-Control-Allow-Origin, possibly together with permitted credentials, that strongly indicates an unchecked reflected configuration.
Does the preflight response need to be checked too?
As a rule, yes. Many cross-origin requests first trigger an OPTIONS preflight request whose response defines the permitted methods and headers. An overly permissive preflight response stays invisible if only the simple read path is considered. A thorough check therefore covers both stages.
Start in 60 seconds

Let XICTRAQ watch your website.

Permanent free plan available. No credit card, no installation, no hidden fees.