chore(security): pin JWT algorithm + SameSite and harden OAuth2 state cookie

- Set GinJWTMiddleware.SigningAlgorithm to "HS256" explicitly so a future
  library default change (or an alg:none confusion attempt) cannot weaken
  token validation. This matches the current gin-jwt default, so behaviour
  is unchanged.
- Set CookieSameSite to Lax: same as the modern-browser default, but
  pinned so server-side intent is clear and CSRF on cross-site POST is
  blocked while top-level GET (OAuth callback) still works.
- Move the nz-o2s OAuth2 state cookie into writeOauth2StateCookie and
  set HttpOnly=true. The frontend does not read this cookie, so HttpOnly
  is strictly an XSS-hardening win with no behaviour change.

JWT Cookie HttpOnly/Secure are intentionally left default for now: the
frontend reads \`!!document.cookie\` to display login state and many
deployments terminate TLS at an upstream proxy — flipping those would
require a coordinated frontend change.

Co-authored-by: naiba/CloudCode <hi+cloudcode@nai.ba>
This commit is contained in:
naiba
2026-05-18 15:17:59 +00:00
co-authored by naiba/CloudCode
parent ee01a174fb
commit 59ccc12e58
3 changed files with 76 additions and 9 deletions
+11 -2
View File
@@ -66,12 +66,21 @@ func oauth2redirect(c *gin.Context) (*model.Oauth2LoginResponse, error) {
}, cache.DefaultExpiration)
url := o2conf.AuthCodeURL(state, oauth2.AccessTypeOnline)
// CodeQL go/cookie-secure-not-set: 根据请求协议动态设置 Secure 属性,避免 HTTP 环境下 Cookie 无法使用
c.SetCookie("nz-o2s", stateKey, 60*5, "", "", c.Request.URL.Scheme == "https" || c.Request.TLS != nil, false)
writeOauth2StateCookie(c, stateKey)
return &model.Oauth2LoginResponse{Redirect: url}, nil
}
// writeOauth2StateCookie sets the nz-o2s cookie used to authenticate the
// OAuth2 callback. Secure is set when the request arrives over HTTPS;
// HttpOnly is enabled unconditionally — the frontend does not read this
// cookie, only the dashboard's callback handler does, so HTTP-only access
// is strictly an XSS-hardening win.
func writeOauth2StateCookie(c *gin.Context, stateKey string) {
secure := c.Request.URL.Scheme == "https" || c.Request.TLS != nil
c.SetCookie("nz-o2s", stateKey, 60*5, "", "", secure, true)
}
// @Summary Unbind Oauth2
// @Description Unbind Oauth2
// @Accept json