diff options
author | Unknwon <u@gogs.io> | 2017-03-31 16:19:10 -0400 |
---|---|---|
committer | Unknwon <u@gogs.io> | 2017-03-31 16:19:10 -0400 |
commit | 761bb3cf53960485921ad045bae5a79340d66f97 (patch) | |
tree | 7f8e475e64cbd9ba6f485891092478cba028c96c /modules/markup/sanitizer.go | |
parent | c1c269d9ef50595475cf4c6728d9b20a6417c490 (diff) |
modules/markup: protect sanitizer from possible modification
Only expose public APIs for 'Sanitize' and 'SanitizeBytes' to
eliminate unintentional modifications to sanitizer policy. Also
use 'sync.Once' to make sure multiple calls of 'NewSanitizer' is
safe (although should never happen, but this is a better way).
Diffstat (limited to 'modules/markup/sanitizer.go')
-rw-r--r-- | modules/markup/sanitizer.go | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/modules/markup/sanitizer.go b/modules/markup/sanitizer.go new file mode 100644 index 00000000..f685657b --- /dev/null +++ b/modules/markup/sanitizer.go @@ -0,0 +1,55 @@ +// Copyright 2017 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package markup + +import ( + "regexp" + "sync" + + "github.com/microcosm-cc/bluemonday" + log "gopkg.in/clog.v1" + + "github.com/gogits/gogs/modules/setting" +) + +// Sanitizer is a protection wrapper of *bluemonday.Policy which does not allow +// any modification to the underlying policies once it's been created. +type Sanitizer struct { + policy *bluemonday.Policy + init sync.Once +} + +var sanitizer = &Sanitizer{} + +// NewSanitizer initializes sanitizer with allowed attributes based on settings. +// Multiple calls to this function will only create one instance of Sanitizer during +// entire application lifecycle. +func NewSanitizer() { + log.Trace("Markup: sanitizer initialization requested") + sanitizer.init.Do(func() { + sanitizer.policy = bluemonday.UGCPolicy() + // We only want to allow HighlightJS specific classes for code blocks + sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^language-\w+$`)).OnElements("code") + + // Checkboxes + sanitizer.policy.AllowAttrs("type").Matching(regexp.MustCompile(`^checkbox$`)).OnElements("input") + sanitizer.policy.AllowAttrs("checked", "disabled").OnElements("input") + + // Custom URL-Schemes + sanitizer.policy.AllowURLSchemes(setting.Markdown.CustomURLSchemes...) + + log.Trace("Markup: sanitizer initialized") + }) +} + +// Sanitize takes a string that contains a HTML fragment or document and applies policy whitelist. +func Sanitize(s string) string { + return sanitizer.policy.Sanitize(s) +} + +// SanitizeBytes takes a []byte slice that contains a HTML fragment or document and applies policy whitelist. +func SanitizeBytes(b []byte) []byte { + return sanitizer.policy.SanitizeBytes(b) +} |