October 29, 2026
From P4 to P1 — Day 6: CORS Misconfigurations in Bug Bounty Hunting
Series: From P4 to P1: The Bug Hunter’s Journey Day: 06/30 Topic: CORS, Cross-Origin Requests, and Sensitive Data Exposure

By cyb3rD1vvy@
7 min read
Introduction
During web application testing, you may encounter an API that returns the following HTTP response header:
Access-Control-Allow-Origin: *
Is this a vulnerability?
Not necessarily.
Cross-Origin Resource Sharing (CORS) is a browser security mechanism that controls whether a webpage from one origin can read responses from another origin. It allows applications to share resources across different domains while enforcing rules defined by the server.
However, an incorrectly configured CORS policy can expose sensitive information to an untrusted website under certain conditions.
For bug bounty hunters, the challenge isn't simply finding a CORS header. It's understanding whether the configuration allows an unauthorized origin to access data that should remain protected.
In Day 5, we explored open redirects. Today, we'll examine how cross-origin policies work, how to identify potential misconfigurations, and how to determine whether they create a genuine security risk.
1. What is CORS?
CORS stands for Cross-Origin Resource Sharing.
Browsers enforce the same-origin policy, which generally prevents JavaScript running on one origin from reading responses from another origin unless permission is granted.
An origin consists of three components:
- Scheme, such as
https - Hostname, such as
example.com - Port, such as
443
For example, these are different origins:
CORS allows a server to specify which origins may read its responses through HTTP headers.
Consider this response:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Content-Type: application/jsonHTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Content-Type: application/jsonThis indicates that the server permits the specified origin to read the response through browser-based cross-origin requests, subject to the browser's CORS rules and any other applicable restrictions.
CORS does not replace authentication or authorization. A server must still ensure that each request is permitted to access the requested resource.
2. Important CORS response headers
Before testing CORS, understand the headers that influence browser behavior.
A. Access-Control-Allow-Origin
This header identifies the origin permitted to read a response.
Example:
Access-Control-Allow-Origin: https://app.example.comAccess-Control-Allow-Origin: https://app.example.comA wildcard configuration looks like this:
Access-Control-Allow-Origin: *Access-Control-Allow-Origin: *The wildcard permits any origin to read responses that are otherwise accessible through browser cross-origin requests. However, it cannot be used to authorize credentialed browser requests in the same way as an explicitly permitted origin.
A wildcard is not automatically a vulnerability. Public APIs serving public information may use it intentionally.
B. Access-Control-Allow-Credentials
This header indicates whether the browser may expose a credentialed cross-origin response to the requesting script when the request uses the appropriate credentials mode.
Example:
Access-Control-Allow-Credentials: trueAccess-Control-Allow-Credentials: trueWhen credentialed access is allowed, the server generally needs to specify an explicit allowed origin rather than *.
The presence of this header alone does not prove that sensitive data is accessible. The origin policy, browser behavior, authentication mechanism, and actual response content all matter.
C. Access-Control-Allow-Methods
This header advertises the HTTP methods permitted for cross-origin requests, particularly during preflight handling.
Example:
Access-Control-Allow-Methods: GET, POST, OPTIONSAccess-Control-Allow-Methods: GET, POST, OPTIONSIts presence does not automatically grant permission to perform every listed operation. The server's own access controls still apply.
D. Access-Control-Allow-Headers
This header identifies request headers that the browser may permit JavaScript to send during applicable cross-origin requests.
Example:
Access-Control-Allow-Headers: Content-Type, AuthorizationAccess-Control-Allow-Headers: Content-Type, AuthorizationAgain, this is part of the browser's cross-origin mechanism, not a replacement for server-side validation.
3. What makes a CORS configuration vulnerable?
The most important distinction is between a permissive configuration and a demonstrable security impact.
Scenario A: Wildcard access to public data
An API returns publicly available product information with:
Access-Control-Allow-Origin: *Access-Control-Allow-Origin: *If the data is intended to be public and does not expose sensitive information, this may be an appropriate configuration.
Result: The wildcard alone is generally insufficient to establish a vulnerability.
Scenario B: Arbitrary origin reflection
An API receives an Origin header and returns that origin in Access-Control-Allow-Origin without properly validating it.
For example, a request includes:
Origin: https://untrusted.exampleOrigin: https://untrusted.exampleAnd the server responds:
Access-Control-Allow-Origin: https://untrusted.example
Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin: https://untrusted.example
Access-Control-Allow-Credentials: trueIf the server also permits a victim's authenticated browser session to access sensitive information, an attacker-controlled website may be able to read that information under the relevant browser conditions.
Result: This can represent a serious CORS misconfiguration if unauthorized access to sensitive data is demonstrated.
Scenario C: Unsafe trust in subdomains
A server may allow all origins that appear to belong to a particular domain or trust every subdomain without considering whether those subdomains can be controlled by untrusted parties.
If a permitted subdomain is vulnerable to takeover or hosts untrusted content, the trust relationship may create an attack path.
Result: Investigate the actual trust boundary and demonstrate the security consequence before assigning severity.
4. How to test CORS manually
Only perform these tests on applications and APIs you own or are explicitly authorized to assess.
Step 1: Inspect the normal response
Start with a normal request to an in-scope endpoint.
curl -sS -D - -o /dev/null https://example.com/api/profilecurl -sS -D - -o /dev/null https://example.com/api/profileReview the response for headers such as:
Access-Control-Allow-Origin:
Access-Control-Allow-Credentials:
Vary: OriginAccess-Control-Allow-Origin:
Access-Control-Allow-Credentials:
Vary: OriginThe absence or presence of any one of these headers is not, by itself, a complete vulnerability assessment.
Step 2: Send a controlled Origin header
Use a reserved example domain to inspect how the server handles an untrusted origin.
curl -sS -D - -o /dev/null \
-H 'Origin: https://untrusted.example' \
https://example.com/api/profilecurl -sS -D - -o /dev/null \
-H 'Origin: https://untrusted.example' \
https://example.com/api/profileObserve whether the server:
- Returns no CORS permission
- Returns an explicitly configured trusted origin
- Reflects the supplied origin
- Returns a wildcard origin
Remember that curl does not enforce browser CORS rules. It shows you the HTTP response, which you must interpret correctly.
Step 3: Compare the results
Repeat the request with an expected trusted origin, if known, and compare the responses.
Check whether the application uses a fixed allowlist, reflects arbitrary values, or applies different policies across endpoints.
If the server dynamically selects an allowed origin, Vary: Origin may also be relevant to caching behavior. Its absence is not automatically a vulnerability; investigate whether responses could be cached and served across origins incorrectly.
Step 4: Identify the data being protected
Determine whether the endpoint returns:
- Public information
- User-specific account data
- Personal information
- Authentication-related information
- Other sensitive business data
A permissive CORS policy on a public endpoint may have little security impact. The same policy on a sensitive, authenticated endpoint deserves closer investigation.
Step 5: Validate the browser behavior
Where authorized, use a controlled test environment and a test account to determine whether an untrusted webpage can actually read the relevant response through a browser.
Do not collect another user's data, use real victims, or expose live session tokens.
The objective is to demonstrate the browser's access to the response, not merely to show that a server returns permissive headers.
5. Common CORS testing mistakes
Mistake 1: Reporting every wildcard
Access-Control-Allow-Origin: * can be appropriate for public resources. Evaluate what the endpoint exposes.
Mistake 2: Treating curl output as proof of browser exploitation
Command-line HTTP clients do not enforce browser CORS restrictions. A response visible in curl may not be readable by JavaScript in a browser.
Mistake 3: Claiming account takeover without evidence
CORS misconfiguration may expose information, but it does not automatically allow an attacker to take over an account.
Mistake 4: Ignoring authentication requirements
An endpoint may require a valid session, an authorization token, or other controls. Understand how those controls affect the potential attack.
Mistake 5: Confusing CORS with CSRF
Cross-Site Request Forgery (CSRF) concerns causing a victim's browser to perform an unwanted action. CORS primarily governs whether browser JavaScript may read cross-origin responses and, in applicable cases, whether certain requests can be made.
The two mechanisms interact, but they are not interchangeable.
Mistake 6: Ignoring the affected data
A permissive policy becomes much more significant when it allows an untrusted origin to read sensitive information that the user is authorized to access but the attacker is not.
6. How to write a professional CORS vulnerability report
The following is a sample report template. Use it only if the behavior described has actually been confirmed on your authorized target.
Title: CORS Misconfiguration Allows an Untrusted Origin to Read Sensitive API Responses
Description:
During the security assessment, the application's API was observed permitting a cross-origin request from an untrusted origin. The response included CORS headers that allowed the requesting origin to read the response under the tested conditions.
The affected endpoint returned sensitive information associated with an authenticated test account. Browser-based validation confirmed that an untrusted origin could read the response when the applicable authentication conditions were met.
Steps to Reproduce:
- Access the authorized application using a designated test account.
- Identify the affected API endpoint.
- Send a request containing an untrusted
Originheader. - Inspect the response's CORS headers.
- Using a controlled test page and account, verify whether browser JavaScript can read the sensitive response.
- Record the relevant headers and a redacted example of the exposed data.
Impact:
An attacker may be able to host a webpage that causes an authenticated victim's browser to make a cross-origin request and read sensitive API information that should not be accessible to the attacker's origin.
The impact depends on the sensitivity of the returned data, the authentication mechanism, and the conditions required for exploitation.
Remediation:
- Maintain an explicit allowlist of trusted origins.
- Avoid reflecting arbitrary
Originvalues. - Do not permit credentialed cross-origin access from untrusted origins.
- Apply appropriate CORS policies consistently across sensitive API endpoints.
- Review caching behavior when responses vary by origin.
- Retain server-side authentication and authorization checks.
- Test the final policy in supported browsers.
Severity: Depends on the sensitivity of the exposed data and the demonstrated attack path. A confirmed exposure of sensitive authenticated data may warrant a higher rating than a permissive header on a public endpoint.
Do not submit this template as a confirmed finding unless your own evidence supports each claim.
7. Day 6 validation checklist
Before reporting a CORS issue, ask yourself:
- Is the endpoint within the authorized scope?
- Have I inspected the relevant response headers?
- Does the server permit an untrusted origin?
- Is the endpoint returning sensitive information?
- Does the endpoint require authentication?
- Have I tested actual browser behavior?
- Have I considered other security controls?
- Can I demonstrate the impact without accessing other users' data?
- Does the report follow the program's scope and severity policy?
Final thoughts
CORS is one of those topics where a small configuration detail can look alarming without necessarily representing a vulnerability.
The strongest reports connect three things: an unsafe cross-origin policy, data or functionality that should be protected, and a reproducible demonstration of unauthorized access.
Remember: A permissive CORS header is an observation. Unauthorized access to protected data is the security impact you need to investigate.
This is Day 6 of From P4 to P1: The Bug Hunter's Journey. Each day, we're building stronger testing habits by moving beyond scanner output and focusing on what the evidence actually proves.
Coming tomorrow — Day 7: IDOR and Broken Object-Level Authorization. How can changing an object identifier expose another user's data?
Follow along for the next part of the series.