mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-23 08:16:49 +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 commit b8db8cdf9c)
This commit is contained in:
@@ -1091,6 +1091,7 @@ func TestCheckTOTP(t *testing.T) {
|
||||
type fields struct {
|
||||
sessionWriteModel *SessionWriteModel
|
||||
eventstore func(*testing.T) *eventstore.Eventstore
|
||||
tarpit Tarpit
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@@ -1109,6 +1110,7 @@ func TestCheckTOTP(t *testing.T) {
|
||||
aggregate: sessAgg,
|
||||
},
|
||||
eventstore: expectEventstore(),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
wantErr: zerrors.ThrowInvalidArgument(nil, "COMMAND-8N9ds", "Errors.User.UserIDMissing"),
|
||||
},
|
||||
@@ -1124,6 +1126,7 @@ func TestCheckTOTP(t *testing.T) {
|
||||
eventstore: expectEventstore(
|
||||
expectFilterError(io.ErrClosedPipe),
|
||||
),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
wantErr: io.ErrClosedPipe,
|
||||
},
|
||||
@@ -1143,6 +1146,7 @@ func TestCheckTOTP(t *testing.T) {
|
||||
),
|
||||
),
|
||||
),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
wantErr: zerrors.ThrowPreconditionFailed(nil, "COMMAND-3Mif9s", "Errors.User.MFA.OTP.NotReady"),
|
||||
},
|
||||
@@ -1169,6 +1173,7 @@ func TestCheckTOTP(t *testing.T) {
|
||||
eventFromEventPusher(org.NewLockoutPolicyAddedEvent(ctx, orgAgg, 0, 0, false)),
|
||||
),
|
||||
),
|
||||
tarpit: expectTarpit(1),
|
||||
},
|
||||
wantErrorCommands: []eventstore.Command{
|
||||
user.NewHumanOTPCheckFailedEvent(ctx, userAgg, nil),
|
||||
@@ -1198,6 +1203,7 @@ func TestCheckTOTP(t *testing.T) {
|
||||
eventFromEventPusher(org.NewLockoutPolicyAddedEvent(ctx, orgAgg, 1, 1, false)),
|
||||
),
|
||||
),
|
||||
tarpit: expectTarpit(1),
|
||||
},
|
||||
wantErrorCommands: []eventstore.Command{
|
||||
user.NewHumanOTPCheckFailedEvent(ctx, userAgg, nil),
|
||||
@@ -1225,6 +1231,7 @@ func TestCheckTOTP(t *testing.T) {
|
||||
),
|
||||
expectFilter(), // recheck
|
||||
),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
wantEventCommands: []eventstore.Command{
|
||||
user.NewHumanOTPCheckSucceededEvent(ctx, userAgg, nil),
|
||||
@@ -1253,6 +1260,7 @@ func TestCheckTOTP(t *testing.T) {
|
||||
user.NewUserLockedEvent(ctx, userAgg),
|
||||
),
|
||||
),
|
||||
tarpit: expectTarpit(0),
|
||||
},
|
||||
wantErr: zerrors.ThrowPreconditionFailed(nil, "COMMAND-SF3fg", "Errors.User.Locked"),
|
||||
},
|
||||
@@ -1264,11 +1272,13 @@ func TestCheckTOTP(t *testing.T) {
|
||||
eventstore: tt.fields.eventstore(t),
|
||||
totpAlg: cryptoAlg,
|
||||
now: func() time.Time { return testNow },
|
||||
tarpit: tt.fields.tarpit.tarpit,
|
||||
}
|
||||
gotCmds, err := CheckTOTP(tt.code)(ctx, cmd)
|
||||
require.ErrorIs(t, err, tt.wantErr)
|
||||
assert.Equal(t, tt.wantErrorCommands, gotCmds)
|
||||
assert.Equal(t, tt.wantEventCommands, cmd.eventCommands)
|
||||
tt.fields.tarpit.metExpectedCalls(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user