Files
nezha_domains/cmd/dashboard/controller/oauth2_csrf_test.go
T
naibaandcloudcode 834ae25024 fix(security): verify transfer-token HMAC and sign CSRF double-submit cookie
- consumeTransferToken now recomputes and constant-time compares the
  entry's HMAC-SHA256; previously the signature was minted but never
  checked, so the documented "防篡改" guarantee was hollow and security
  rested solely on the sync.Map key's randomness.
- CSRF switches from a raw-random double-submit cookie to a signed token
  (nonce.HMAC-SHA256 keyed by JWTSecretKey). The middleware now also
  validates the signature, defeating sibling-subdomain cookie tossing
  where a naive header==cookie pair would otherwise pass.

Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
2026-05-31 05:48:50 +00:00

30 lines
832 B
Go

package controller
import (
"net/http/httptest"
"strings"
"testing"
"github.com/gin-gonic/gin"
)
// setCSRFCookie must mint a readable nz-csrf cookie; OAuth2 callback relies on
// it so OAuth-only sessions can satisfy the double-submit CSRF gate.
func TestSetCSRFCookieIssuesReadableToken(t *testing.T) {
gin.SetMode(gin.TestMode)
withCSRFSecret(t, "test-jwt-secret")
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest("GET", "/", nil)
setCSRFCookie(c)
setCookie := w.Header().Get("Set-Cookie")
if !strings.Contains(setCookie, csrfCookieName+"=") {
t.Fatalf("expected %s cookie, got %q", csrfCookieName, setCookie)
}
if strings.Contains(strings.ToLower(setCookie), "httponly") {
t.Fatal("CSRF cookie must be JS-readable (not HttpOnly) for the SPA to mirror it")
}
}