Server resend request cookies in response with different parameters
Expected Behavior
Server does not return request cookies with incorrect parameters in the response.
Current Behavior
Server return in response cookies from request with incorrect parameters.
Possible Solution
Separate request cookies from other cookies in Cookies.Storage and do not return request cookies in the response?
Steps to Reproduce (for bugs)
- Set in browser some cookie with specific parameters (expires, path)
- Send request to the server with that cookie
- In response will be a Set-Cookie header with different parameters (empty parameters, or specific from server configuration)
- Now browser either has two identical cookies that differ in parameters, or updates the existing cookie.
Context
If I understand correctly, all requests are processed in App.handler(). Cookies from request are loaded into the Cookies.Storage here and when ctx.saveCookies() is called, cookies from Cookies.Storage are placed in the response headers. Server knows about cookies from the request only their name and value, so all other cookies parameters will be changed.
This behavior can be dangerous, since server can make the authorization cookie accessible for javascript from the browser (remove the httponly and secure flags).
I'm just starting to analyze a project that uses gramework, so I apologize if I'm wrong and this behavior is either customizable or has nothing to do with gramework at all. For the moment, we just added pre-middleware, which removes everything from Cookie.Storage, but it seems like a bad solution.
Your Environment
- Version used: v1.7.0-rc3
- Environment name and version: go1.13 on Alpine or MacOS 10.14.6
- Server type and version: Local MacOS 10.14.6 or Kubernetes
Issue is still present in 1.7 release. This can be "problematic" for settings Secure and/or HttpOnly attributes. (Which should be used 95% of time when dealing with cookies)
I did not see what's the added value for cookies compared to use "directly" fasthttp implementation : parsing all cookies into string and resend it for all requests, isn't really cost free. Did i miss something ?
Your Environment
- Version used: v1.7.0
- Environment name and version: go1.16 on Alpine
- Server type and version: go1.16 on Alpine
Possible solutions
I'm able to help if needed, just tell me if the first solution below can be considered ?
- Use fasthttp implementation directly (possibly with some helpers)
Alternative :
- Add option to disable cookie handling in Gramework. (This permit to "manually" use fasthttp implementation thought
ctx.RequestCtx.Response.Header--> cost saving, and remove middleware needed compared to workaround bellow)
Possible Workaround until fix
-
Set cookie using fasthttp api :
ctx.RequestCtx.Response.Header.SetCookie()Example :cookie := fasthttp.Cookie{} cookie.SetKey("mySecureCookie") cookie.SetValue("true") cookie.SetSecure(true) cookie.SetHTTPOnly(true) ctx.RequestCtx.Response.Header.SetCookie(&cookie) -
Then, in add after (or before as suggested by Arimeka) request middleware to cleanup Gramework cookies (to avoid erasing cookie : this issue subject)
app.UseAfterRequest(func(ctx *gramework.Context) { // cleanup gramework cookie, because it resend all cookies received at each request. see https://github.com/gramework/gramework/issues/71 for k := range ctx.Cookies.Storage { delete(ctx.Cookies.Storage, k) } })