mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-24 11:58:25 +00:00
fix: respect lockout policy on password change (with old password) and add tar pit for checks
# Which Problems Are Solved While the lockout policy was correctly applied on the session API and other authentication and management endpoints , it had no effect on the user service v2 endpoints. # How the Problems Are Solved - Correctly apply lockout policy on the user service v2 endpoints. - Added tar pitting to auth factor checks (authentication and management API) to prevent brute-force attacks or denial of service because of user lockouts. - Tar pitting is not active if `IgnoreUnknownUsername` option is active to prevent leaking information whether a user exists or not. # Additional Changes None # Additional Context - requires backports * cleanup (cherry picked from commitb8db8cdf9c) (cherry picked from commitd3713dfaed)
This commit is contained in:
@@ -2096,6 +2096,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
newEncryptedCodeWithDefault encryptedCodeWithDefaultFunc
|
||||
checkPermission domain.PermissionCheck
|
||||
defaultSecretGenerators *SecretGenerators
|
||||
tarpit Tarpit
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -2131,6 +2132,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
expectFilter(),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2156,6 +2158,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckNotAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2177,6 +2180,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
expectFilter(),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2220,6 +2224,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2247,6 +2252,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2274,6 +2280,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckNotAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2322,6 +2329,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2356,6 +2364,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2410,6 +2419,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
newCode: mockEncryptedCode("emailCode", time.Hour),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2440,6 +2450,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2469,6 +2480,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckNotAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2506,6 +2518,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2541,6 +2554,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2590,6 +2604,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
newCode: mockEncryptedCode("emailCode", time.Hour),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2672,6 +2687,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
newEncryptedCodeWithDefault: mockEncryptedCodeWithDefault("phoneCode", time.Hour),
|
||||
defaultSecretGenerators: defaultGenerators,
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2747,6 +2763,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
newEncryptedCodeWithDefault: mockEncryptedCodeWithDefault("phoneCode", time.Hour),
|
||||
defaultSecretGenerators: defaultGenerators,
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2777,6 +2794,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckNotAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2814,6 +2832,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2849,6 +2868,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2928,6 +2948,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
newEncryptedCodeWithDefault: mockEncryptedCodeWithDefault("phoneCode", time.Hour),
|
||||
defaultSecretGenerators: defaultGenerators,
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2955,6 +2976,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
eventstore: expectEventstore(),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -2988,6 +3010,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -3020,6 +3043,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(), // recheck of user locking relevant events
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
|
||||
@@ -3035,6 +3059,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -3059,6 +3084,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
eventstore: expectEventstore(),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -3093,6 +3119,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
checkPermission: newMockPermissionCheckNotAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -3147,6 +3174,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -3180,6 +3208,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(), // recheck of user locking relevant events
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
|
||||
@@ -3203,6 +3232,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -3237,9 +3267,27 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
),
|
||||
),
|
||||
expectFilter(), // recheck of user locking relevant events
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
org.NewLockoutPolicyAddedEvent(context.Background(),
|
||||
&userAgg.Aggregate,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
user.NewHumanPasswordCheckFailedEvent(context.Background(),
|
||||
&userAgg.Aggregate,
|
||||
nil,
|
||||
),
|
||||
),
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
tarpit: expectTarpit(1),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -3311,6 +3359,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -3365,6 +3414,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -3429,6 +3479,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -3487,6 +3538,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
@@ -3509,7 +3561,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "change human password and password encoded, password code, encoded used",
|
||||
name: "change human password encoded, old password, ok",
|
||||
fields: fields{
|
||||
eventstore: expectEventstore(
|
||||
expectFilter(
|
||||
@@ -3561,15 +3613,15 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
),
|
||||
checkPermission: newMockPermissionCheckAllowed(),
|
||||
userPasswordHasher: mockPasswordHasher("x"),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
orgID: "org1",
|
||||
human: &ChangeHuman{
|
||||
Password: &Password{
|
||||
Password: "passwordnotused",
|
||||
OldPassword: "password",
|
||||
EncodedPasswordHash: "$plain$x$password2",
|
||||
PasswordCode: "code",
|
||||
ChangeRequired: true,
|
||||
},
|
||||
},
|
||||
@@ -3594,6 +3646,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
checkPermission: tt.fields.checkPermission,
|
||||
defaultSecretGenerators: tt.fields.defaultSecretGenerators,
|
||||
userEncryption: tt.args.codeAlg,
|
||||
tarpit: tt.fields.tarpit.tarpit,
|
||||
}
|
||||
err := r.ChangeUserHuman(tt.args.ctx, tt.args.human, tt.args.codeAlg)
|
||||
if tt.res.err == nil {
|
||||
@@ -3609,6 +3662,7 @@ func TestCommandSide_ChangeUserHuman(t *testing.T) {
|
||||
assert.Equal(t, tt.res.wantEmailCode, tt.args.human.EmailCode)
|
||||
assert.Equal(t, tt.res.wantPhoneCode, tt.args.human.PhoneCode)
|
||||
}
|
||||
tt.fields.tarpit.metExpectedCalls(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user