Skip to content

Permissive CORS configuration on hosted.rudderlabs.com/v1/batch reflects arbitrary origins with credentials enabled #7359

Description

@sriman0707

Description

The https://hosted.rudderlabs.com/v1/batch endpoint has a permissive Cross-Origin Resource Sharing (CORS) configuration.

The endpoint reflects an arbitrary attacker-controlled origin, such as https://evil.com, in the Access-Control-Allow-Origin response header while also setting Access-Control-Allow-Credentials: true.

This behavior is present in both the CORS preflight response and the actual POST response.

I have attached screenshots showing the requests and responses demonstrating this behavior.

Severity

Low

The permissive CORS behavior is confirmed, but the tested endpoint currently requires a RudderStack write key and returns 401 Unauthorized without one. I have therefore not claimed unauthorized access to sensitive customer data.

Steps to Reproduce

Step 1 — Send a CORS preflight request

Send the following request:

OPTIONS /v1/batch HTTP/2
Host: hosted.rudderlabs.com
Origin: https://evil.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type

Step 2 — Observe the response

The server responds with:

HTTP/2 204
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: https://evil.com
Image

Step 3 — Send the actual POST request

Send:

POST /v1/batch HTTP/2
Host: hosted.rudderlabs.com
Origin: https://evil.com
Content-Type: application/json

{}

Step 4 — Observe the response

The server responds with:

HTTP/2 401
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://evil.com

The response body indicates:

failed to read writekey from header
Image

Expected Result

The server should only allow explicitly trusted origins.

For an untrusted origin such as https://evil.com, the server should not return:

Access-Control-Allow-Origin: https://evil.com
Access-Control-Allow-Credentials: true

The CORS policy should instead reject the untrusted origin or omit the CORS authorization headers.

Actual Result

The server accepts the attacker-controlled origin https://evil.com and returns:

Access-Control-Allow-Origin: https://evil.com
Access-Control-Allow-Credentials: true

This occurs for both the preflight request and the actual POST request.

Impact

An overly permissive CORS policy can potentially allow an attacker-controlled website to make cross-origin requests to the affected endpoint and, depending on the authentication mechanism and behavior of other authenticated endpoints, potentially access information or perform actions in the security context of a victim.

For the tested /v1/batch endpoint, an unauthenticated request currently returns 401 Unauthorized because a RudderStack write key is required. Therefore, the impact demonstrated by this proof of concept is currently limited to the permissive CORS configuration itself.

The same CORS policy should be reviewed across other authenticated RudderStack endpoints to ensure that sensitive resources are not exposed through the same configuration.

Remediation

  • Replace arbitrary origin reflection with an explicit allowlist of trusted origins.
  • Do not allow untrusted origins such as https://evil.com.
  • Only use Access-Control-Allow-Credentials: true when credentialed cross-origin access is explicitly required.
  • Apply strict origin validation on the server side.
  • Review other authenticated API endpoints for the same CORS configuration.
  • Ensure sensitive API responses are not accessible to unauthorized cross-origin origins.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions