mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
LoginAttempt: Add setting to control max number of attempts before user login gets locked (#97091)
* Add setting to adjust number of login attempts before user login gets locked * Ensure at least one attempt can be made * Update documentation with new setting * Update docs/sources/setup-grafana/configure-grafana/_index.md Co-authored-by: Eric Leijonmarck <eric.leijonmarck@gmail.com>
This commit is contained in:
parent
f2b96593ea
commit
b2626a2d65
@ -351,6 +351,9 @@ data_source_proxy_whitelist =
|
||||
# disable protection against brute force login attempts
|
||||
disable_brute_force_login_protection = false
|
||||
|
||||
# max number of failed login attempts before user gets locked
|
||||
brute_force_login_protection_max_attempts = 5
|
||||
|
||||
# set to true if you host Grafana behind HTTPS. default is false.
|
||||
cookie_secure = false
|
||||
|
||||
|
@ -350,6 +350,9 @@
|
||||
# disable protection against brute force login attempts
|
||||
;disable_brute_force_login_protection = false
|
||||
|
||||
# max number of failed login attempts before user gets locked
|
||||
;brute_force_login_protection_max_attempts = 5
|
||||
|
||||
# set to true if you host Grafana behind HTTPS. default is false.
|
||||
;cookie_secure = false
|
||||
|
||||
|
@ -630,7 +630,11 @@ Define a whitelist of allowed IP addresses or domains, with ports, to be used in
|
||||
|
||||
### disable_brute_force_login_protection
|
||||
|
||||
Set to `true` to disable [brute force login protection](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#account-lockout). Default is `false`. An existing user's account will be locked after 5 attempts in 5 minutes.
|
||||
Set to `true` to disable [brute force login protection](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#account-lockout). Default is `false`. An existing user's account will be unable to login for 5 minutes if all login attempts are spent within a 5 minute window.
|
||||
|
||||
### brute_force_login_protection_max_attempts
|
||||
|
||||
Configure how many login attempts a user have within a 5 minute window before the account will be locked. Default is `5`.
|
||||
|
||||
### cookie_secure
|
||||
|
||||
|
@ -11,10 +11,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
maxInvalidLoginAttempts int64 = 5
|
||||
loginAttemptsWindow = time.Minute * 5
|
||||
)
|
||||
const loginAttemptsWindow = time.Minute * 5
|
||||
|
||||
func ProvideService(db db.DB, cfg *setting.Cfg, lock *serverlock.ServerLockService) *Service {
|
||||
return &Service{
|
||||
@ -80,7 +77,7 @@ func (s *Service) Validate(ctx context.Context, username string) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if count >= maxInvalidLoginAttempts {
|
||||
if count >= s.cfg.BruteForceLoginProtectionMaxAttempts {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,8 @@ import (
|
||||
)
|
||||
|
||||
func TestService_Validate(t *testing.T) {
|
||||
const maxInvalidLoginAttempts = 5
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
loginAttempts int64
|
||||
@ -64,6 +66,7 @@ func TestService_Validate(t *testing.T) {
|
||||
for _, tt := range testCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
cfg.BruteForceLoginProtectionMaxAttempts = maxInvalidLoginAttempts
|
||||
cfg.DisableBruteForceLoginProtection = tt.disabled
|
||||
service := &Service{
|
||||
store: fakeStore{
|
||||
@ -84,6 +87,7 @@ func TestLoginAttempts(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cfg := setting.NewCfg()
|
||||
cfg.DisableBruteForceLoginProtection = false
|
||||
cfg.BruteForceLoginProtectionMaxAttempts = 5
|
||||
db := db.InitTestDB(t)
|
||||
service := ProvideService(db, cfg, nil)
|
||||
|
||||
|
@ -154,18 +154,19 @@ type Cfg struct {
|
||||
RendererDefaultImageScale float64
|
||||
|
||||
// Security
|
||||
DisableInitAdminCreation bool
|
||||
DisableBruteForceLoginProtection bool
|
||||
CookieSecure bool
|
||||
CookieSameSiteDisabled bool
|
||||
CookieSameSiteMode http.SameSite
|
||||
AllowEmbedding bool
|
||||
XSSProtectionHeader bool
|
||||
ContentTypeProtectionHeader bool
|
||||
StrictTransportSecurity bool
|
||||
StrictTransportSecurityMaxAge int
|
||||
StrictTransportSecurityPreload bool
|
||||
StrictTransportSecuritySubDomains bool
|
||||
DisableInitAdminCreation bool
|
||||
DisableBruteForceLoginProtection bool
|
||||
BruteForceLoginProtectionMaxAttempts int64
|
||||
CookieSecure bool
|
||||
CookieSameSiteDisabled bool
|
||||
CookieSameSiteMode http.SameSite
|
||||
AllowEmbedding bool
|
||||
XSSProtectionHeader bool
|
||||
ContentTypeProtectionHeader bool
|
||||
StrictTransportSecurity bool
|
||||
StrictTransportSecurityMaxAge int
|
||||
StrictTransportSecurityPreload bool
|
||||
StrictTransportSecuritySubDomains bool
|
||||
// CSPEnabled toggles Content Security Policy support.
|
||||
CSPEnabled bool
|
||||
// CSPTemplate contains the Content Security Policy template.
|
||||
@ -1498,7 +1499,14 @@ func readSecuritySettings(iniFile *ini.File, cfg *Cfg) error {
|
||||
security := iniFile.Section("security")
|
||||
cfg.SecretKey = valueAsString(security, "secret_key", "")
|
||||
cfg.DisableGravatar = security.Key("disable_gravatar").MustBool(true)
|
||||
|
||||
cfg.DisableBruteForceLoginProtection = security.Key("disable_brute_force_login_protection").MustBool(false)
|
||||
cfg.BruteForceLoginProtectionMaxAttempts = security.Key("brute_force_login_protection_max_attempts").MustInt64(5)
|
||||
|
||||
// Ensure at least one login attempt can be performed.
|
||||
if cfg.BruteForceLoginProtectionMaxAttempts <= 0 {
|
||||
cfg.BruteForceLoginProtectionMaxAttempts = 1
|
||||
}
|
||||
|
||||
CookieSecure = security.Key("cookie_secure").MustBool(false)
|
||||
cfg.CookieSecure = CookieSecure
|
||||
|
Loading…
Reference in New Issue
Block a user