added dummy bcrypt check
This commit is contained in:
@@ -85,8 +85,8 @@ func TestDefaultRateLimitMiddleware(t *testing.T) {
|
|||||||
{"/norate", 0, false, 200},
|
{"/norate", 0, false, 200},
|
||||||
|
|
||||||
{"/rate/a", 0, false, 200},
|
{"/rate/a", 0, false, 200},
|
||||||
{"/rate/a", 700, false, 200}, // (fixed window check) wait enough to ensure that it can't fit more than 2 requests in 1s
|
{"/rate/a", 800, false, 200}, // (fixed window check) wait enough to ensure that it can't fit more than 2 requests in 1s
|
||||||
{"/rate/a", 800, false, 200},
|
{"/rate/a", 500, false, 200},
|
||||||
{"/rate/a", 800, false, 200},
|
{"/rate/a", 800, false, 200},
|
||||||
{"/rate/a", 0, false, 200},
|
{"/rate/a", 0, false, 200},
|
||||||
{"/rate/a", 0, false, 429},
|
{"/rate/a", 0, false, 429},
|
||||||
|
|||||||
@@ -85,6 +85,11 @@ func recordAuthWithPassword(e *core.RequestEvent) error {
|
|||||||
|
|
||||||
return e.App.OnRecordAuthWithPasswordRequest().Trigger(event, func(e *core.RecordAuthWithPasswordRequestEvent) error {
|
return e.App.OnRecordAuthWithPasswordRequest().Trigger(event, func(e *core.RecordAuthWithPasswordRequestEvent) error {
|
||||||
if e.Record == nil || !e.Record.ValidatePassword(e.Password) {
|
if e.Record == nil || !e.Record.ValidatePassword(e.Password) {
|
||||||
|
// dummy password check to minimize enumeration side-channel attacks
|
||||||
|
if e.Record == nil {
|
||||||
|
dummyPasswordCheck(e.App, e.Collection)
|
||||||
|
}
|
||||||
|
|
||||||
return e.BadRequestError("Failed to authenticate.", errors.New("invalid login credentials"))
|
return e.BadRequestError("Failed to authenticate.", errors.New("invalid login credentials"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,6 +120,21 @@ func (form *authWithPasswordForm) validate(collection *core.Collection) error {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dummy password check to minimize side-channel attacks
|
||||||
|
// (performed with the collection configured field cost)
|
||||||
|
func dummyPasswordCheck(app core.App, collection *core.Collection) {
|
||||||
|
record := &core.Record{}
|
||||||
|
|
||||||
|
// find any random existing record
|
||||||
|
err := app.RecordQuery(collection).Limit(1).One(record)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// the value and result doesn't matter, we just need a constant-time check
|
||||||
|
_ = record.ValidatePassword("")
|
||||||
|
}
|
||||||
|
|
||||||
func findRecordByIdentityField(app core.App, collection *core.Collection, field string, value any) (*core.Record, error) {
|
func findRecordByIdentityField(app core.App, collection *core.Collection, field string, value any) (*core.Record, error) {
|
||||||
if !slices.Contains(collection.PasswordAuth.IdentityFields, field) {
|
if !slices.Contains(collection.PasswordAuth.IdentityFields, field) {
|
||||||
return nil, errors.New("invalid identity field " + field)
|
return nil, errors.New("invalid identity field " + field)
|
||||||
|
|||||||
Reference in New Issue
Block a user