Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: missing sameSite when do context.reset() #3123

Merged
merged 1 commit into from Apr 17, 2022

Conversation

ahuigo
Copy link
Contributor

@ahuigo ahuigo commented Apr 15, 2022

I find a bug about missing sameSite when do context.reset()

Here is the bad case example:

package main

import (
	"bytes"
	"fmt"
	"net/http"
	"net/http/httptest"
	"net/url"
	"strings"

	"github.com/gin-gonic/gin"
)

type responseBodyWriter struct {
	gin.ResponseWriter
	body *bytes.Buffer //cache
}

func (r responseBodyWriter) Write(b []byte) (int, error) {
	r.body.Write(b)
	return r.ResponseWriter.Write(b)
}

func (r responseBodyWriter) WriteString(s string) (n int, err error) {
	r.body.WriteString(s)
	return r.ResponseWriter.WriteString(s)
}

// test gonic context
func main() {
	e := gin.New()

	// middleware
	e.Use(func(c *gin.Context) {
		w := &responseBodyWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer}
		c.Writer = w

		c.Next()
		// body := w.body.String()

		path := c.Request.URL.Path
		header := dumpHeader(w.Header())
		fmt.Printf("path:%s,response header:%s\n", path, header)
		if path == "/http" && strings.Contains(header, "SameSite=None") {
			err := fmt.Errorf("path:%s,response header:%s", path, header)
			panic(err)
		}
	})

	// route
	e.GET("/*any", func(c *gin.Context) {
		if c.Request.URL.Path == "/https" {
			c.SetSameSite(http.SameSiteNoneMode)
		}
		c.SetCookie("count", "1", 1, "", "x.com", false, false)
	})

	// mock requests
	for i := 0; ; i++ {
		URL, _ := url.Parse("http://x.com/https")
		if i%2 == 0 {
			URL, _ = url.Parse("http://x.com/http")
		}
		req := &http.Request{
			Method:     "GET",
			Header:     make(http.Header),
			Proto:      "HTTP/1.1",
			ProtoMajor: 1,
			ProtoMinor: 1,
			URL:        URL,
		}
		writer := httptest.NewRecorder()
		e.ServeHTTP(writer, req)
	}

}

func dumpHeader(header http.Header) string {
	var res strings.Builder
	headers := sortHeader(header)
	for _, kv := range headers {
		res.WriteString(kv[0] + ": " + kv[1] + "\n")
	}
	return res.String()
}

// sortHeaders
func sortHeader(header http.Header) [][2]string {
	headers := [][2]string{}
	for k, vs := range header {
		for _, v := range vs {
			headers = append(headers, [2]string{k, v})
		}
	}
	n := len(headers)
	for i := 0; i < n; i++ {
		for j := n - 1; j > i; j-- {
			jj := j - 1
			h1, h2 := headers[j], headers[jj]
			if h1[0] < h2[0] {
				headers[jj], headers[j] = headers[j], headers[jj]
			}
		}
	}
	return headers
}

@ahuigo ahuigo changed the title fix: missing sameSite when do context.reset() Fix: missing sameSite when do context.reset() Apr 15, 2022
.gitignore Outdated
@@ -1,4 +1,5 @@
vendor/*
/.vscode
Copy link
Member

@appleboy appleboy Apr 16, 2022

Choose a reason for hiding this comment

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

revert this setting

Copy link
Contributor Author

@ahuigo ahuigo Apr 16, 2022

Choose a reason for hiding this comment

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

I've reverted it.
This bug would causes panic error when running my example.

@appleboy appleboy added the bug label Apr 16, 2022
@appleboy appleboy added this to the v1.8 milestone Apr 16, 2022
@codecov
Copy link

codecov bot commented Apr 16, 2022

Codecov Report

Merging #3123 (6e976ca) into master (c458094) will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@           Coverage Diff           @@
##           master    #3123   +/-   ##
=======================================
  Coverage   98.77%   98.77%           
=======================================
  Files          41       41           
  Lines        3105     3106    +1     
=======================================
+ Hits         3067     3068    +1     
  Misses         26       26           
  Partials       12       12           
Flag Coverage Δ
go-1.14 98.77% <100.00%> (+<0.01%) ⬆️
go-1.15 98.61% <100.00%> (+<0.01%) ⬆️
go-1.16 98.59% <100.00%> (+<0.01%) ⬆️
go-1.17 98.51% <100.00%> (+<0.01%) ⬆️
go-1.18 98.51% <100.00%> (+<0.01%) ⬆️
macos-latest 98.77% <100.00%> (+<0.01%) ⬆️
nomsgpack 98.75% <100.00%> (+<0.01%) ⬆️
ubuntu-latest 98.77% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
context.go 97.91% <100.00%> (+<0.01%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c458094...6e976ca. Read the comment docs.

@appleboy appleboy merged commit 6854212 into gin-gonic:master Apr 17, 2022
26 checks passed
daheige pushed a commit to daheige/gin that referenced this issue Apr 18, 2022
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.

None yet

2 participants