From 0c03773c4c14f510e06d3fbbd69d7f300a842779 Mon Sep 17 00:00:00 2001 From: Gabe Kangas Date: Wed, 28 Dec 2022 21:30:06 -0800 Subject: [PATCH] Sanitize+truncate display names on registration+change. For #2527 --- controllers/chat.go | 7 +++++-- core/chat/events.go | 5 ++--- utils/strings.go | 29 +++++++++++++++++++++++++++++ utils/strings_test.go | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 utils/strings.go create mode 100644 utils/strings_test.go diff --git a/controllers/chat.go b/controllers/chat.go index 6dd40bdd0..9b4305647 100644 --- a/controllers/chat.go +++ b/controllers/chat.go @@ -4,9 +4,11 @@ import ( "encoding/json" "net/http" + "github.com/owncast/owncast/config" "github.com/owncast/owncast/core/chat" "github.com/owncast/owncast/core/user" "github.com/owncast/owncast/router/middleware" + "github.com/owncast/owncast/utils" log "github.com/sirupsen/logrus" ) @@ -76,7 +78,8 @@ func RegisterAnonymousChatUser(w http.ResponseWriter, r *http.Request) { request.DisplayName = r.Header.Get("X-Forwarded-User") } - newUser, accessToken, err := user.CreateAnonymousUser(request.DisplayName) + proposedNewDisplayName := utils.MakeSafeStringOfLength(request.DisplayName, config.MaxChatDisplayNameLength) + newUser, accessToken, err := user.CreateAnonymousUser(proposedNewDisplayName) if err != nil { WriteSimpleResponse(w, false, err.Error()) return @@ -85,7 +88,7 @@ func RegisterAnonymousChatUser(w http.ResponseWriter, r *http.Request) { response := registerAnonymousUserResponse{ ID: newUser.ID, AccessToken: accessToken, - DisplayName: newUser.DisplayName, + DisplayName: proposedNewDisplayName, } w.Header().Set("Content-Type", "application/json") diff --git a/core/chat/events.go b/core/chat/events.go index 081a1532c..6e10b940d 100644 --- a/core/chat/events.go +++ b/core/chat/events.go @@ -11,6 +11,7 @@ import ( "github.com/owncast/owncast/core/data" "github.com/owncast/owncast/core/user" "github.com/owncast/owncast/core/webhooks" + "github.com/owncast/owncast/utils" log "github.com/sirupsen/logrus" ) @@ -27,9 +28,7 @@ func (s *Server) userNameChanged(eventData chatClientEvent) { blocklist := data.GetForbiddenUsernameList() // Names have a max length - if len(proposedUsername) > config.MaxChatDisplayNameLength { - proposedUsername = proposedUsername[:config.MaxChatDisplayNameLength] - } + proposedUsername = utils.MakeSafeStringOfLength(proposedUsername, config.MaxChatDisplayNameLength) for _, blockedName := range blocklist { normalizedName := strings.TrimSpace(blockedName) diff --git a/utils/strings.go b/utils/strings.go new file mode 100644 index 000000000..1ad45c547 --- /dev/null +++ b/utils/strings.go @@ -0,0 +1,29 @@ +package utils + +import ( + "strings" + + "github.com/microcosm-cc/bluemonday" +) + +// StripHTML will strip HTML tags from a string. +func StripHTML(s string) string { + p := bluemonday.NewPolicy() + return p.Sanitize(s) +} + +// MakeSafeStringOfLength will take a string and strip HTML tags, +// trim whitespace, and limit the length. +func MakeSafeStringOfLength(s string, length int) string { + newString := s + newString = StripHTML(newString) + + if len(newString) > length { + newString = newString[:length] + } + + newString = strings.ReplaceAll(newString, "\r", "") + newString = strings.TrimSpace(newString) + + return newString +} diff --git a/utils/strings_test.go b/utils/strings_test.go new file mode 100644 index 000000000..7d6ea2520 --- /dev/null +++ b/utils/strings_test.go @@ -0,0 +1,32 @@ +package utils + +import ( + "fmt" + "testing" +) + +// TestStripHTML tests the StripHTML function. +func TestStripHTML(t *testing.T) { + requestedString := `

Some text

` + expectedResult := `Some text` + + result := StripHTML(requestedString) + fmt.Println(result) + + if result != expectedResult { + t.Errorf("Expected %s, got %s", expectedResult, result) + } +} + +// TestSafeString tests the TestSafeString function. +func TestSafeString(t *testing.T) { + requestedString := `

Some text blah blah blah blah blah blahb albh

` + expectedResult := `Some te` + + result := MakeSafeStringOfLength(requestedString, 10) + fmt.Println(result) + + if result != expectedResult { + t.Errorf("Expected %s, got %s", expectedResult, result) + } +}