From 1aa649f67db546e3cfab8a5f5232c30800500cd0 Mon Sep 17 00:00:00 2001 From: Evan Johnson Date: Wed, 25 Jul 2018 09:11:23 -0700 Subject: [PATCH] Fix * behavior to be standard compliant. When a user specifies *, then * should be returned by the server in the access-control-allow-origin header, not the origin header. All implementations of the CORS standard that reflect the origin header when * is specified are incorrect, because an Access-Control-Allow-Origin header of '*' has a different meaning than a reflected Origin header. Refer to Section 6.1 https://www.w3.org/TR/cors/. When * is set, Credentials are not allowed to be used in an authenticated request. **What's the big deal?** If you set Allow Credentials to True and Origins to * with this library then you have turned off SAMEORIGIN policy for your website, which is unexpected behavior and....really bad. --- cors.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/cors.go b/cors.go index d85d86c..4a49cab 100644 --- a/cors.go +++ b/cors.go @@ -19,6 +19,7 @@ package cors import ( + "fmt" "log" "net/http" "os" @@ -26,6 +27,10 @@ import ( "strings" ) +func init() { + fmt.Println("hi") +} + // Options is a configuration container to setup the CORS middleware. type Options struct { // AllowedOrigins is a list of origins a cross-domain request can be executed from. @@ -236,7 +241,7 @@ func (c *Cors) handlePreflight(w http.ResponseWriter, r *http.Request) { c.logf("Preflight aborted: headers '%v' not allowed", reqHeaders) return } - headers.Set("Access-Control-Allow-Origin", origin) + headers.Set("Access-Control-Allow-Origin", c.FetchOrigin(origin)) // Spec says: Since the list of methods can be unbounded, simply returning the method indicated // by Access-Control-Request-Method (if supported) can be enough headers.Set("Access-Control-Allow-Methods", strings.ToUpper(reqMethod)) @@ -287,7 +292,7 @@ func (c *Cors) handleActualRequest(w http.ResponseWriter, r *http.Request) { return } - headers.Set("Access-Control-Allow-Origin", origin) + headers.Set("Access-Control-Allow-Origin", c.FetchOrigin(origin)) if len(c.exposedHeaders) > 0 { headers.Set("Access-Control-Expose-Headers", strings.Join(c.exposedHeaders, ", ")) } @@ -304,6 +309,13 @@ func (c *Cors) logf(format string, a ...interface{}) { } } +func (c *Cors) FetchOrigin(origin string) string { + if c.IsStar() { + return "*" + } + return origin +} + // isOriginAllowed checks if a given origin is allowed to perform cross-domain requests // on the endpoint func (c *Cors) isOriginAllowed(r *http.Request, origin string) bool { @@ -327,6 +339,10 @@ func (c *Cors) isOriginAllowed(r *http.Request, origin string) bool { return false } +func (c *Cors) IsStar() bool { + return c.allowedOriginsAll +} + // isMethodAllowed checks if a given method can be used as part of a cross-domain request // on the endpoing func (c *Cors) isMethodAllowed(method string) bool {