From 7dbac1cdf7c156f0bcadb02bc06c23872b7ae6c6 Mon Sep 17 00:00:00 2001 From: John Brooks Date: Tue, 27 Dec 2016 17:38:51 -0700 Subject: [PATCH] core: Add functions to sanitize nicknames and messages --- core/contactlist.go | 8 +++++-- core/sanitize.go | 56 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 core/sanitize.go diff --git a/core/contactlist.go b/core/contactlist.go index be8bf14..1ab0012 100644 --- a/core/contactlist.go +++ b/core/contactlist.go @@ -84,12 +84,16 @@ func (this *ContactList) AddContactRequest(address, name, fromName, text string) if !IsAddressValid(address) { return nil, errors.New("Invalid ricochet address") } + if len(fromName) > 0 && !IsNicknameAcceptable(fromName) { + return nil, errors.New("Invalid nickname") + } + if len(text) > 0 && !IsMessageAcceptable(text) { + return nil, errors.New("Invalid message") + } this.mutex.Lock() defer this.mutex.Unlock() - // XXX validity checks on name/text also useful - for _, contact := range this.contacts { if contact.Address() == address { return nil, errors.New("Contact already exists with this address") diff --git a/core/sanitize.go b/core/sanitize.go new file mode 100644 index 0000000..ed43edc --- /dev/null +++ b/core/sanitize.go @@ -0,0 +1,56 @@ +package core + +import ( + "unicode" + "unicode/utf8" +) + +// IsNicknameAcceptable returns true for strings that are usable as contact nicknames. +// A nickname is acceptable if it: +// - Is composed of only valid UTF-8 sequences +// - Has between 1 and MaxNicknameLength unicode characters +// - Doesn't contain any characters from unicode Cf or Cc +// - Doesn't contain any of these HTML-sensitive characters: "<>&\ +// - XXX This could use more thought on valid codepoints; note that Go +// has a good set of built-in range tables in `unicode` +func IsNicknameAcceptable(nickname string) bool { + length := 0 + + blacklist := []rune{'"', '<', '>', '&', '\\'} + + for len(nickname) > 0 { + r, sz := utf8.DecodeRuneInString(nickname) + if r == utf8.RuneError { + return false + } + + if unicode.In(r, unicode.Cf, unicode.Cc) { + return false + } + + for _, br := range blacklist { + if r == br { + return false + } + } + + length++ + if length > MaxNicknameLength { + return false + } + nickname = nickname[sz:] + } + + return length > 0 +} + +// IsMessageAcceptable returns true for strings that are usable as chat messages. +// A message is acceptable if it: +// - Is composed of only valid UTF-8 sequences +// - Encodes to between 1 and MaxMessageLength bytes in UTF-8 +// - XXX This also needs more thought on valid unicode characters +func IsMessageAcceptable(message string) bool { + return len(message) > 0 && + len(message) <= MaxMessageLength && + utf8.ValidString(message) +}