Skip to content

fix(csrf): honor Secure(false) option for request URL scheme detection - #215

Closed
AdamMagued wants to merge 1 commit into
gorilla:mainfrom
AdamMagued:fix-insecure-sameorigin-scheme
Closed

AdamMagued wants to merge 1 commit into
gorilla:mainfrom
AdamMagued:fix-insecure-sameorigin-scheme

Conversation

@AdamMagued

Copy link
Copy Markdown

Technical Explanation & Root Cause Analysis

In gorilla/csrf, when evaluating requests with non-idempotent HTTP methods (such as POST), the middleware constructs a shallow copy of r.URL to determine the origin and compare against incoming Origin headers via sameOrigin(a, b):

requestURL := *r.URL // shallow clone

requestURL.Scheme = "https"
if isPlaintext {
    requestURL.Scheme = "http"
}
if requestURL.Host == "" {
    requestURL.Host = r.Host
}

Because server requests in Go's net/http do not populate r.URL.Scheme, the scheme defaults to "https" unless explicit plaintext context is provided via PlaintextHTTPRequest (isPlaintext).

When users configure the middleware for local development over plain HTTP using csrf.Secure(false), isPlaintext remains false. As a result, incoming requests with Origin: http://localhost:8080 (and Host: localhost:8080) are compared against requestURL.Scheme = "https", causing sameOrigin(&requestURL, parsedOrigin) to fail due to scheme mismatch and incorrectly rejecting the request with ErrBadOrigin (HTTP 403 Forbidden).

Solution

Update the request URL scheme determination to also check if the Secure(false) option is set on the middleware (!cs.opts.Secure):

requestURL.Scheme = "https"
if isPlaintext || !cs.opts.Secure {
    requestURL.Scheme = "http"
}

When csrf.Secure(false) is enabled, the scheme defaults to "http", allowing same-origin checks against plain HTTP origins to succeed without requiring manual additions to TrustedOrigins.

Test Verification

Added TestInsecureOriginSameOrigin in csrf_test.go:

  • Configures csrf.Protect with csrf.Secure(false).
  • Dispatches a POST request with Host: localhost:8080 and Origin: http://localhost:8080.
  • Verifies that the request is accepted without ErrBadOrigin (returns HTTP 200 OK).
  • Verified full test suite passes with race detection and statement coverage.

Fixes #188

@AdamMagued

Copy link
Copy Markdown
Author

Closing in favor of earlier community PR #212 to avoid duplicate review effort.

@AdamMagued AdamMagued closed this Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] v.1.7.3 sameOrigin check issue for localhost over http

1 participant