fix(identity): 拒绝跨站浏览器会话端点
统一认证使用 HttpOnly SameSite=Strict 会话 Cookie。配对时若 Public Base 与 Web Base 不属于同一 schemeful site,浏览器回调会丢失事务 Cookie。新增基于 Public Suffix List 的同站校验,并在运行时重建时重复门禁,防止旧持久化数据绕过。 验证:go test ./... -count=1(apps/api)
This commit is contained in:
@@ -70,6 +70,57 @@ func TestValidatePairingInputRejectsRemoteHTTPAndURLCredentials(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidatePairingInputRejectsCrossSiteBrowserEndpoints(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
appEnv string
|
||||
input PairingInput
|
||||
}{
|
||||
{
|
||||
name: "different registrable domains",
|
||||
appEnv: "production",
|
||||
input: PairingInput{
|
||||
AuthCenterURL: "https://auth.example.com", PublicBaseURL: "https://api.example.com",
|
||||
WebBaseURL: "https://gateway.example.net", LocalTenantKey: "default",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "different loopback sites",
|
||||
appEnv: "test",
|
||||
input: PairingInput{
|
||||
AuthCenterURL: "http://127.0.0.1:18000", PublicBaseURL: "http://127.0.0.1:18088",
|
||||
WebBaseURL: "http://localhost:15178", LocalTenantKey: "default",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "different schemes",
|
||||
appEnv: "test",
|
||||
input: PairingInput{
|
||||
AuthCenterURL: "http://127.0.0.1:18000", PublicBaseURL: "http://localhost:18088",
|
||||
WebBaseURL: "https://localhost:15178", LocalTenantKey: "default",
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if _, err := test.input.ConsumerMetadata(false, test.appEnv); err == nil {
|
||||
t.Fatalf("cross-site browser endpoints were accepted: %#v", test.input)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateRevisionURLsRejectsCrossSiteBrowserEndpoints(t *testing.T) {
|
||||
revision := Revision{
|
||||
AuthCenterURL: "https://auth.example.com",
|
||||
Issuer: "https://auth.example.com/issuer/shared",
|
||||
PublicBaseURL: "https://api.example.com",
|
||||
WebBaseURL: "https://gateway.example.net",
|
||||
}
|
||||
if err := ValidateRevisionURLs(revision, "production"); err == nil {
|
||||
t.Fatal("cross-site persisted browser endpoints were accepted")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewDraftAppliesSessionDefaultsWithoutPersistingOnboardingCode(t *testing.T) {
|
||||
draft, err := NewDraft(PairingInput{
|
||||
AuthCenterURL: "https://auth.example.com", OnboardingCode: "onb1.must-never-be-persisted",
|
||||
@@ -91,7 +142,7 @@ func TestNewDraftAppliesSessionDefaultsWithoutPersistingOnboardingCode(t *testin
|
||||
func TestNewDraftAllowsLoopbackHTTPOnlyInLocalEnvironments(t *testing.T) {
|
||||
localInput := PairingInput{
|
||||
AuthCenterURL: "http://localhost:18000", PublicBaseURL: "http://127.0.0.1:18089",
|
||||
WebBaseURL: "http://localhost:5178", LocalTenantKey: "default",
|
||||
WebBaseURL: "http://127.0.0.1:5178", LocalTenantKey: "default",
|
||||
}
|
||||
secureInput := PairingInput{
|
||||
AuthCenterURL: "https://auth.example.com", PublicBaseURL: "https://api.example.com",
|
||||
|
||||
Reference in New Issue
Block a user