Skip to content

Fix CORS header duplication in chained proxies#2990

Open
BiosSystem wants to merge 1 commit into
labstack:masterfrom
BiosSystem:fix-cors-header-duplication
Open

Fix CORS header duplication in chained proxies#2990
BiosSystem wants to merge 1 commit into
labstack:masterfrom
BiosSystem:fix-cors-header-duplication

Conversation

@BiosSystem

Copy link
Copy Markdown

Fixes #2853.

When Echo CORS middleware is run in a chained proxy setup (or in front of any handler copying upstream headers using Add), headers like Access-Control-Allow-Origin and Vary get duplicated in the response.

Changes:

  • Run simple request CORS header writing inside a Before hook on the response. This allows the proxy's CORS config to cleanly Set the headers, overriding duplicated upstream headers from the proxy or downstream response copy.
  • Implement addVaryHeader helper to merge and deduplicate Vary values case-insensitively.
  • Add unit test simulating ReverseProxy behavior to verify headers are not duplicated.

@aldas

aldas commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

I do not think this is a good idea. I do not think this is sustainable for middlewares to start adding extra logic so they work potentially with some other middleware. and res.Before(func() { is such dark magic of Echo and really hard to debug that I really do not want to accept it for maintainability reasons.

Are we lacking mechnisms (callbacks/handler funcs etc) at the moment in middlewares to allow for you to plug-in these work-a-rounds at your app/repo?

Copilot AI 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.

Pull request overview

This PR fixes duplicated CORS-related response headers (notably Access-Control-Allow-Origin and Vary) when Echo’s CORS middleware is used in chained proxy scenarios where upstream headers are copied with Header.Add.

Changes:

  • Moves simple-request CORS header writing into Response.Before(...) hooks so the middleware can Set/dedupe headers after an upstream/proxy handler has Added them.
  • Adds an addVaryHeader helper to merge and deduplicate Vary values case-insensitively.
  • Adds a unit test that simulates reverse-proxy-style header copying to ensure CORS headers are not duplicated.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
middleware/cors.go Defers simple-request CORS header writes via Response.Before and introduces addVaryHeader for deduping Vary.
middleware/cors_test.go Adds a regression test simulating proxy header copying to verify no duplication of CORS/Vary headers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread middleware/cors.go
Comment on lines +318 to +331
func addVaryHeader(h http.Header, value string) {
if h.Get(echo.HeaderVary) == "" {
h.Set(echo.HeaderVary, value)
return
}
for _, v := range h.Values(echo.HeaderVary) {
for _, part := range strings.Split(v, ",") {
if strings.EqualFold(strings.TrimSpace(part), value) {
return
}
}
}
h.Add(echo.HeaderVary, value)
}
Comment thread middleware/cors.go
Comment on lines 241 to 247
// no CORS middleware should block non-preflight requests;
// such requests should be let through. One reason is that not all requests that
// carry an Origin header participate in the CORS protocol.
res.Before(func() {
addVaryHeader(res.Header(), echo.HeaderOrigin)
})
return next(c)
@aldas

aldas commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

As I said I am not in favor of this PR, especially because of Response.Before usage.

just for information - there is similar PR agains v4 #2983

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.

CORS middleware duplicates headers when used in chained proxy servers

3 participants