From 8f2dc0693f25055d366586cea77a7bd20505091b Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Fri, 13 Nov 2026 03:19:01 -0800 Subject: [PATCH] s3api: test that session claims keep only the server-asserted aws:userid Co-Authored-By: Claude Opus 5.5 --- weed/s3api/auth_sts_identity_test.go | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/weed/s3api/auth_sts_identity_test.go b/weed/s3api/auth_sts_identity_test.go index a1e2dbca38..db854a83f5 100644 --- a/weed/s3api/auth_sts_identity_test.go +++ b/weed/s3api/auth_sts_identity_test.go @@ -394,3 +394,41 @@ func newTestIdentity(policyNames []string) *Identity { PolicyNames: policyNames, } } + +func TestSTSSessionClaimsKeepOnlyServerAssertedUserID(t *testing.T) { + stsService, config := setupTestSTSService(t) + iam := NewIdentityAccessManagementWithStore(&S3ApiServerOption{}, nil, "memory") + iam.SetIAMIntegration(&S3IAMIntegration{stsService: stsService}) + victim := sts.ComputeParentUser("alice", "https://idp.example") + attacker := sts.ComputeParentUser("mallory", "https://idp.example") + + for name, tc := range map[string]struct{ parentUser, want string }{ + "no parent user": {"", ""}, + "parent user": {attacker, attacker}, + } { + t.Run(name, func(t *testing.T) { + claims := sts.NewSTSSessionClaims("userid-"+strings.ReplaceAll(name, " ", "-"), config.Issuer, time.Now().Add(time.Hour)). + WithSessionName("userid"). + WithRoleInfo("arn:aws:iam::role/testRole", "arn:aws:sts::assumed-role/testRole/userid", "arn:aws:sts::assumed-role/testRole/userid"). + WithRequestContext(map[string]interface{}{"aws:userid": victim, "seaweed:oidc-issuers": "https://idp.example"}) + if tc.parentUser != "" { + claims.WithParentUser(tc.parentUser) + } + token, err := sts.NewTokenGenerator(config.SigningKey, config.Issuer).GenerateJWTWithClaims(claims) + require.NoError(t, err) + sessionInfo, err := stsService.ValidateSessionToken(context.Background(), token) + require.NoError(t, err) + req, err := http.NewRequest(http.MethodGet, "/lake/key", nil) + require.NoError(t, err) + + identity, _, errCode := iam.validateSTSSessionToken(req, token, sessionInfo.Credentials.AccessKeyId) + require.Equal(t, s3err.ErrNone, errCode) + _, hasUserID := identity.Claims["aws:userid"] + assert.Equal(t, tc.want != "", hasUserID) + if tc.want != "" { + assert.Equal(t, tc.want, identity.Claims["aws:userid"]) + } + assert.NotContains(t, identity.Claims, "seaweed:oidc-issuers") + }) + } +}