diff --git a/compose/service/values/sanitizer.go b/compose/service/values/sanitizer.go index 2dd081e4b..5af1769e5 100644 --- a/compose/service/values/sanitizer.go +++ b/compose/service/values/sanitizer.go @@ -2,15 +2,13 @@ package values import ( "fmt" - "html" - "regexp" "strconv" "strings" "time" "github.com/cortezaproject/corteza-server/pkg/expr" "github.com/cortezaproject/corteza-server/pkg/logger" - "github.com/microcosm-cc/bluemonday" + "github.com/cortezaproject/corteza-server/pkg/xss" "go.uber.org/zap" "github.com/cortezaproject/corteza-server/compose/types" @@ -286,23 +284,8 @@ func sNumber(num interface{}, p uint) string { return str } -// sString is used mostly to strip insecure html data -// from strings func sString(str string) string { - // use standard html escaping policy - p := bluemonday.UGCPolicy() - - // match only colors for html editor elements on style attr - p.AllowAttrs("style").OnElements("span", "p") - p.AllowStyles("color").Matching(regexp.MustCompile("(?i)^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$")).Globally() - p.AllowStyles("background-color").Matching(regexp.MustCompile("(?i)^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$")).Globally() - - sanitized := p.Sanitize(str) - - // handle escaped strings and unescape them - // all the dangerous chars should have been stripped - // by now - return html.UnescapeString(sanitized) + return xss.RichText(str) } // sanitize casts value to field kind format diff --git a/pkg/locale/input.go b/pkg/locale/input.go index 118eb8242..70153093c 100644 --- a/pkg/locale/input.go +++ b/pkg/locale/input.go @@ -1,15 +1,9 @@ package locale import ( - "html" - - "github.com/microcosm-cc/bluemonday" -) - -var ( - stripHtml = bluemonday.StripTagsPolicy().Sanitize + "github.com/cortezaproject/corteza-server/pkg/xss" ) func SanitizeMessage(in string) string { - return html.UnescapeString(stripHtml(in)) + return xss.RichText(in) } diff --git a/pkg/locale/input_test.go b/pkg/locale/input_test.go index 47238ad5d..06c679223 100644 --- a/pkg/locale/input_test.go +++ b/pkg/locale/input_test.go @@ -14,10 +14,8 @@ func Test_SanitizeMessage(t *testing.T) { }{ {"simple", "abc", "abc"}, {"accents", "čšž", "čšž"}, - {"html", "čšž", "čšž"}, - {"broken html 1", "čšžčšžčšž"}, - {"broken html 3", "čšž", "čšž"}, + {"unsafe html", `XSS`, "XSS"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/xss/rich_text.go b/pkg/xss/rich_text.go new file mode 100644 index 000000000..47dc576f1 --- /dev/null +++ b/pkg/xss/rich_text.go @@ -0,0 +1,26 @@ +package xss + +import ( + "html" + "regexp" + + "github.com/microcosm-cc/bluemonday" +) + +// RichText assures safe HTML content +func RichText(in string) string { + // use standard html escaping policy + p := bluemonday.UGCPolicy() + + // match only colors for html editor elements on style attr + p.AllowAttrs("style").OnElements("span", "p") + p.AllowStyles("color").Matching(regexp.MustCompile("(?i)^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$")).Globally() + p.AllowStyles("background-color").Matching(regexp.MustCompile("(?i)^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$")).Globally() + + sanitized := p.Sanitize(in) + + // handle escaped strings and unescape them + // all the dangerous chars should have been stripped + // by now + return html.UnescapeString(sanitized) +}