From e5dfacb4bbcf1e19c82523fe145d4d6951d82631 Mon Sep 17 00:00:00 2001 From: Daniel Heath Date: Thu, 15 Feb 2018 20:10:27 +1100 Subject: [PATCH] Update to latest teeny-security: Makes brute-forcing access codes much harder --- Gopkg.lock | 2 +- .../gin-teeny-security/gin-teeny-security.go | 23 +++++++++++++++---- .../gin-teeny-security_test.go | 7 ++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 768d3ef..7754f5a 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -29,7 +29,7 @@ branch = "master" name = "github.com/danielheath/gin-teeny-security" packages = ["."] - revision = "5f00fb6ac0933c2b378c907a3e2a43667afc4289" + revision = "b9ad6bd1a94e8e68fd1256221b3e055c8af5f81a" [[projects]] name = "github.com/garyburd/redigo" diff --git a/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security.go b/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security.go index c73c772..4cc5f17 100644 --- a/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security.go +++ b/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security.go @@ -6,8 +6,9 @@ import "github.com/gin-gonic/gin" import "github.com/gin-contrib/sessions" import "net/http" import "net/url" -import "fmt" import "io" +import "time" +import "sync" import "html/template" // Forces you to a login page until you provide a secret code. @@ -32,6 +33,9 @@ type Config struct { Template *template.Template SaveKeyToSession func(*gin.Context, string) GetKeyFromSession func(*gin.Context) string + + LoginAttemptSlowdown time.Duration + mutex sync.Mutex } func (c Config) saveKey(ctx *gin.Context, k string) { @@ -58,7 +62,6 @@ func DefaultGetSession(c *gin.Context) string { session := sessions.Default(c) str, ok := session.Get("secretAccessCode").(string) if !ok { - fmt.Println(session.Get("secretAccessCode")) return "" } return str @@ -85,6 +88,13 @@ func (c Config) template() *template.Template { return c.Template } +func (c Config) loginSlowdown() time.Duration { + if c.LoginAttemptSlowdown == 0 { + return time.Second + } + return c.LoginAttemptSlowdown +} + func (c Config) ExecTemplate(w io.Writer, message, returnUrl string) error { return c.template().Execute(w, LoginPageParams{ Message: message, @@ -101,7 +111,7 @@ var DEFAULT_LOGIN_PAGE = template.Must(template.New("login").Parse(`

Login

{{ if .Message }}

{{ .Message }}

{{ end }}
- +
`)) @@ -114,11 +124,14 @@ func (cfg *Config) Middleware(c *gin.Context) { } if c.Request.Method == "POST" { + // slow down brute-force attacks + cfg.mutex.Lock() + defer cfg.mutex.Unlock() + time.Sleep(cfg.loginSlowdown()) + c.Request.ParseForm() - fmt.Println(c.Request.PostForm.Get("secretAccessCode")) if c.Request.PostForm.Get("secretAccessCode") == cfg.Secret { - c.Header("Location", returnTo) cfg.saveKey(c, cfg.Secret) diff --git a/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security_test.go b/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security_test.go index f16d121..c490d1e 100644 --- a/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security_test.go +++ b/vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security_test.go @@ -7,6 +7,8 @@ import "net/http" import "net/url" import "log" import "io" +import "fmt" +import "time" import "io/ioutil" import "testing" import "github.com/gin-gonic/gin" @@ -73,9 +75,14 @@ func TestAuth(t *testing.T) { mustStartWith("

Login

\n\n
Login\n

Wrong Password

", readString(res.Body)) + finishTime := time.Now() + if finishTime.Before(allowedFinishTime) { + die(fmt.Errorf("Expected failed login to take at least 1 second")) + } // Check entering a good password lets you access things res, err = http.PostForm(ts.URL+"/enter-password/?return=/private/", url.Values{"secretAccessCode": []string{"garden"}})