Skip to content

CORS Reflect Origin#1385

Open
rsrdesarrollo wants to merge 1 commit into
projectdiscovery:mainfrom
rsrdesarrollo:main
Open

CORS Reflect Origin#1385
rsrdesarrollo wants to merge 1 commit into
projectdiscovery:mainfrom
rsrdesarrollo:main

Conversation

@rsrdesarrollo

@rsrdesarrollo rsrdesarrollo commented Jun 4, 2026

Copy link
Copy Markdown

Updates the CORS middleware behavior when OriginURL is configured as *, which is the default value.

Previously, the server returned:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

This combination is invalid for credentialed CORS requests. Browsers reject CORS responses that use Access-Control-Allow-Origin: * together with Access-Control-Allow-Credentials: true.

With this change, when OriginURL is set to *, the middleware reflects the incoming request's Origin header instead of returning * directly.

If OriginURL is configured with a specific value, the existing behavior is preserved and that configured value is returned as Access-Control-Allow-Origin.

This keeps the default CORS behavior permissive while making credentialed CORS requests valid according to browser CORS enforcement rules.

Without this change, cross-origin requests using credentials may fail even though the server explicitly sets Access-Control-Allow-Credentials: true.

Summary by CodeRabbit

  • Bug Fixes
    • Improved CORS (Cross-Origin Resource Sharing) handling to dynamically reflect request origins when wildcard configuration is used, with enhanced support for cross-origin preflight requests.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The CORS middleware in the HTTP server now supports dynamic origin reflection. When the origin configuration is set to "*", the middleware echoes back the incoming request's Origin header instead of using the static configuration value, enabling flexible cross-origin requests while maintaining the same security header setup.

Changes

Dynamic CORS Origin Handling

Layer / File(s) Summary
CORS middleware dynamic origin computation
pkg/server/http_server.go
corsMiddleware computes acao_url from the request Origin header when OriginURL is "*", otherwise uses the configured OriginURL. The computed value is applied consistently to Access-Control-Allow-Origin for both OPTIONS preflight requests (returning 204) and regular requests before proceeding.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Poem

A rabbit hops through CORS gates,
Where origins once were static, fate waits,
Now "*" reflects what requests declare,
Dynamic headers floating fair,
Preflight and real requests now share! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'CORS Reflect Origin' directly and specifically describes the main change: the middleware now reflects the incoming request's Origin header for CORS responses when configured with '*'.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/server/http_server.go`:
- Around line 492-507: The CORS handling sets Access-Control-Allow-Origin
dynamically when h.options.OriginURL == "*" (computed into acao_url from
req.Header.Get("Origin")) but does not set the Vary header; add
w.Header().Add("Vary", "Origin") whenever Access-Control-Allow-Origin is
determined from the request (i.e., in the branch where h.options.OriginURL ==
"*") so both the preflight (req.Method == http.MethodOptions) and normal
response paths include Vary: Origin to prevent incorrect cached responses.
- Around line 492-506: When h.options.OriginURL == "*" only use
req.Header.Get("Origin") if it returns a non-empty string (avoid acao_url = "");
set acao_url := "" by default, then if h.options.OriginURL == "*" do origin :=
req.Header.Get("Origin"); if origin != "" { acao_url = origin } else leave
acao_url empty; for the http.MethodOptions preflight branch and the later
w.Header().Set("Access-Control-Allow-Origin", ...) call only set the
Access-Control-Allow-Origin (and related CORS headers) when acao_url != "" to
avoid emitting an empty header. Reference h.options.OriginURL,
req.Header.Get("Origin"), acao_url, http.MethodOptions and
w.Header().Set("Access-Control-Allow-Origin").
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3ff1c6ca-591c-4045-b572-2ec90947c3d7

📥 Commits

Reviewing files that changed from the base of the PR and between 810180a and 148d9f7.

📒 Files selected for processing (1)
  • pkg/server/http_server.go

Comment thread pkg/server/http_server.go
Comment on lines +492 to +506
if h.options.OriginURL == "*" {
acao_url = req.Header.Get("Origin")
} else {
acao_url = h.options.OriginURL
}

// Set CORS headers for the preflight request
if req.Method == http.MethodOptions {
w.Header().Set("Access-Control-Allow-Origin", h.options.OriginURL)
w.Header().Set("Access-Control-Allow-Origin", acao_url)
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
w.WriteHeader(http.StatusNoContent)
return
}
w.Header().Set("Access-Control-Allow-Origin", h.options.OriginURL)
w.Header().Set("Access-Control-Allow-Origin", acao_url)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid emitting empty Access-Control-Allow-Origin when request has no Origin.

In wildcard mode, non-CORS requests can produce Access-Control-Allow-Origin: "". Prefer setting CORS headers only when Origin is present (or explicitly fallback behavior), so headers stay valid and predictable.

Suggested patch
-		var acao_url string
+		var acao_url string
+		shouldSetCORS := true
 		if h.options.OriginURL == "*" {
 			acao_url = req.Header.Get("Origin")
+			if acao_url == "" {
+				shouldSetCORS = false
+			}
 		} else {
 			acao_url = h.options.OriginURL
 		}
@@
-			w.Header().Set("Access-Control-Allow-Origin", acao_url)
-			w.Header().Set("Access-Control-Allow-Credentials", "true")
-			w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
+			if shouldSetCORS {
+				w.Header().Set("Access-Control-Allow-Origin", acao_url)
+				w.Header().Set("Access-Control-Allow-Credentials", "true")
+				w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
+			}
 			w.WriteHeader(http.StatusNoContent)
 			return
 		}
-		w.Header().Set("Access-Control-Allow-Origin", acao_url)
-		w.Header().Set("Access-Control-Allow-Credentials", "true")
-		w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
+		if shouldSetCORS {
+			w.Header().Set("Access-Control-Allow-Origin", acao_url)
+			w.Header().Set("Access-Control-Allow-Credentials", "true")
+			w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
+		}
 		next.ServeHTTP(w, req)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/server/http_server.go` around lines 492 - 506, When h.options.OriginURL
== "*" only use req.Header.Get("Origin") if it returns a non-empty string (avoid
acao_url = ""); set acao_url := "" by default, then if h.options.OriginURL ==
"*" do origin := req.Header.Get("Origin"); if origin != "" { acao_url = origin }
else leave acao_url empty; for the http.MethodOptions preflight branch and the
later w.Header().Set("Access-Control-Allow-Origin", ...) call only set the
Access-Control-Allow-Origin (and related CORS headers) when acao_url != "" to
avoid emitting an empty header. Reference h.options.OriginURL,
req.Header.Get("Origin"), acao_url, http.MethodOptions and
w.Header().Set("Access-Control-Allow-Origin").

Comment thread pkg/server/http_server.go
Comment on lines +492 to 507
if h.options.OriginURL == "*" {
acao_url = req.Header.Get("Origin")
} else {
acao_url = h.options.OriginURL
}

// Set CORS headers for the preflight request
if req.Method == http.MethodOptions {
w.Header().Set("Access-Control-Allow-Origin", h.options.OriginURL)
w.Header().Set("Access-Control-Allow-Origin", acao_url)
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
w.WriteHeader(http.StatusNoContent)
return
}
w.Header().Set("Access-Control-Allow-Origin", h.options.OriginURL)
w.Header().Set("Access-Control-Allow-Origin", acao_url)
w.Header().Set("Access-Control-Allow-Credentials", "true")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add Vary: Origin when Access-Control-Allow-Origin is dynamic.

When OriginURL == "*", Access-Control-Allow-Origin varies per request origin, but the response currently does not advertise that variance. Shared caches/CDNs can serve a response with the wrong CORS origin to another client.

Suggested patch
 		if h.options.OriginURL == "*" {
 			acao_url = req.Header.Get("Origin")
+			w.Header().Add("Vary", "Origin")
 		} else {
 			acao_url = h.options.OriginURL
 		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if h.options.OriginURL == "*" {
acao_url = req.Header.Get("Origin")
} else {
acao_url = h.options.OriginURL
}
// Set CORS headers for the preflight request
if req.Method == http.MethodOptions {
w.Header().Set("Access-Control-Allow-Origin", h.options.OriginURL)
w.Header().Set("Access-Control-Allow-Origin", acao_url)
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
w.WriteHeader(http.StatusNoContent)
return
}
w.Header().Set("Access-Control-Allow-Origin", h.options.OriginURL)
w.Header().Set("Access-Control-Allow-Origin", acao_url)
w.Header().Set("Access-Control-Allow-Credentials", "true")
if h.options.OriginURL == "*" {
acao_url = req.Header.Get("Origin")
w.Header().Add("Vary", "Origin")
} else {
acao_url = h.options.OriginURL
}
// Set CORS headers for the preflight request
if req.Method == http.MethodOptions {
w.Header().Set("Access-Control-Allow-Origin", acao_url)
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
w.WriteHeader(http.StatusNoContent)
return
}
w.Header().Set("Access-Control-Allow-Origin", acao_url)
w.Header().Set("Access-Control-Allow-Credentials", "true")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/server/http_server.go` around lines 492 - 507, The CORS handling sets
Access-Control-Allow-Origin dynamically when h.options.OriginURL == "*"
(computed into acao_url from req.Header.Get("Origin")) but does not set the Vary
header; add w.Header().Add("Vary", "Origin") whenever
Access-Control-Allow-Origin is determined from the request (i.e., in the branch
where h.options.OriginURL == "*") so both the preflight (req.Method ==
http.MethodOptions) and normal response paths include Vary: Origin to prevent
incorrect cached responses.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant