diff --git a/backend/app/rest/api/rest.go b/backend/app/rest/api/rest.go index 2af430b2..c156faa0 100644 --- a/backend/app/rest/api/rest.go +++ b/backend/app/rest/api/rest.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "net/http" + "net/mail" "regexp" "strings" "sync" @@ -653,11 +654,11 @@ func subscribersOnly(enable bool) func(http.Handler) http.Handler { } // validEmaiAuth is a middleware for auth endpoints for email method. -// it rejects login request if user or email are suspicious +// it rejects login request if user, site or email are suspicious func validEmaiAuth() func(http.Handler) http.Handler { - // matches ui side validation, adding min/max limitation - reUser := regexp.MustCompile(`^[\p{L}\d\s_]{4,64}$`) + reUser := regexp.MustCompile(`^[\p{L}\d\s_]{4,64}$`) // matches ui side validation, adding min/max limitation + reSite := regexp.MustCompile(`^[a-zA-Z\d\s_]{1,64}$`) return func(h http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { @@ -674,6 +675,21 @@ func validEmaiAuth() func(http.Handler) http.Handler { return } } + + if a := r.URL.Query().Get("address"); a != "" { + if _, err := mail.ParseAddress(a); err != nil { + http.Error(w, "Access denied", http.StatusForbidden) + return + } + } + + if s := r.URL.Query().Get("site"); s != "" { + if !reSite.MatchString(s) { + http.Error(w, "Access denied", http.StatusForbidden) + return + } + } + h.ServeHTTP(w, r) } return http.HandlerFunc(fn) diff --git a/backend/app/rest/api/rest_test.go b/backend/app/rest/api/rest_test.go index 7f4b70d9..1700074b 100644 --- a/backend/app/rest/api/rest_test.go +++ b/backend/app/rest/api/rest_test.go @@ -402,6 +402,9 @@ func Test_validEmaiAuth(t *testing.T) { {"/auth/email/login?site=remark42&address=umputun%example.com&user=someonelooong+loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong", http.StatusForbidden}, {"/auth/twitter/login?site=remark42&address=umputun%example.com&user=..blah+blah", http.StatusOK}, {"/auth/email/login?site=remark42&address=umputun%example.com", http.StatusOK}, + {"/auth/email/login?site=remark42&address=umputun+example.com&user=someone", http.StatusForbidden}, + {"/auth/email/login?site=bad!site&address=umputun%example.com&user=someone", http.StatusForbidden}, + {"/auth/email/login?site=loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongsite&address=umputun%example.com&user=someone", http.StatusForbidden}, } for i, tt := range tbl {