Some checks are pending
Security Checks / security (push) Waiting to run
统一 frontend、backend、test、test-log 和 out 目录,更新构建、部署及测试入口;纳入配置管理兼容与首次安全引导修复;排除本机配置、密钥和测试产物。
79 lines
2.2 KiB
Go
79 lines
2.2 KiB
Go
package csrf
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"git.pcux.cn/xuans/Smail/session"
|
|
"github.com/alexedwards/scs/v2"
|
|
)
|
|
|
|
func testRequestWithToken(t *testing.T, manager *scs.SessionManager, stored, header, cookie string) *http.Request {
|
|
t.Helper()
|
|
request := httptest.NewRequest(http.MethodPost, "https://mail.example.com/api/settings", nil)
|
|
loaded, err := manager.Load(request.Context(), "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
request = request.WithContext(loaded)
|
|
if stored != "" {
|
|
manager.Put(request.Context(), SessionKey, stored)
|
|
}
|
|
if header != "" {
|
|
request.Header.Set(HeaderName, header)
|
|
}
|
|
if cookie != "" {
|
|
request.AddCookie(&http.Cookie{Name: CookieName, Value: cookie})
|
|
}
|
|
return request
|
|
}
|
|
|
|
func TestValidRejectsMissingAndMismatchedTokens(t *testing.T) {
|
|
old := session.Instance
|
|
manager := scs.New()
|
|
session.Instance = manager
|
|
t.Cleanup(func() { session.Instance = old })
|
|
|
|
cases := []struct {
|
|
name string
|
|
stored string
|
|
header string
|
|
cookie string
|
|
}{
|
|
{name: "missing-header", stored: "token", cookie: "token"},
|
|
{name: "missing-cookie", stored: "token", header: "token"},
|
|
{name: "header-mismatch", stored: "token", header: "other", cookie: "token"},
|
|
{name: "cookie-mismatch", stored: "token", header: "token", cookie: "other"},
|
|
{name: "missing-session", header: "token", cookie: "token"},
|
|
}
|
|
for _, item := range cases {
|
|
t.Run(item.name, func(t *testing.T) {
|
|
if Valid(testRequestWithToken(t, manager, item.stored, item.header, item.cookie)) {
|
|
t.Fatal("invalid CSRF token combination was accepted")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestClearInvalidatesExistingToken(t *testing.T) {
|
|
old := session.Instance
|
|
manager := scs.New()
|
|
session.Instance = manager
|
|
t.Cleanup(func() { session.Instance = old })
|
|
|
|
request := testRequestWithToken(t, manager, "token", "token", "token")
|
|
if !Valid(request) {
|
|
t.Fatal("valid CSRF token was rejected")
|
|
}
|
|
recorder := httptest.NewRecorder()
|
|
Clear(recorder, request, true)
|
|
if Valid(request) {
|
|
t.Fatal("cleared CSRF token remained valid")
|
|
}
|
|
cookies := recorder.Result().Cookies()
|
|
if len(cookies) != 1 || cookies[0].Name != CookieName || cookies[0].MaxAge >= 0 || !cookies[0].Secure {
|
|
t.Fatalf("unexpected CSRF clear cookie: %+v", cookies)
|
|
}
|
|
}
|