11package sanitize
22
33import (
4- "github.com/microcosm-cc/bluemonday"
4+ "sync"
5+
6+ "github.com/microcosm-cc/bluemonday"
57)
68
79var policy * bluemonday.Policy
10+ var policyOnce sync.Once
811
912func Sanitize (input string ) string {
1013 return FilterHTMLTags (FilterInvisibleCharacters (input ))
@@ -31,24 +34,44 @@ func FilterInvisibleCharacters(input string) string {
3134}
3235
3336func FilterHTMLTags (input string ) string {
34- if policy == nil {
35- policyInit ()
36- }
37+ if policy == nil {
38+ policyInit ()
39+ }
3740 if input == "" {
3841 return input
3942 }
4043 return policy .Sanitize (input )
4144}
4245
4346func policyInit () {
44- if policy != nil {
45- return
46- }
47- policy = bluemonday .StrictPolicy ()
48- policy .AllowElements ("b" , "blockquote" , "br" , "code" , "em" , "h1" , "h2" , "h3" , "h4" , "h5" , "h6" , "hr" , "i" , "li" , "ol" , "p" , "pre" , "strong" , "sub" , "sup" , "table" , "tbody" , "td" , "th" , "thead" , "tr" , "ul" )
49- policy .AllowAttrs ("img" , "a" )
50- policy .AllowURLSchemes ("https" )
51- policy .AllowImages ()
47+ policyOnce .Do (func () {
48+ p := bluemonday .StrictPolicy ()
49+
50+ // Safe textual/formatting elements only
51+ p .AllowElements (
52+ "b" , "blockquote" , "br" , "code" , "em" ,
53+ "h1" , "h2" , "h3" , "h4" , "h5" , "h6" ,
54+ "hr" , "i" , "li" , "ol" , "p" , "pre" ,
55+ "strong" , "sub" , "sup" , "table" , "tbody" ,
56+ "td" , "th" , "thead" , "tr" , "ul" ,
57+ // Explicitly allow anchors and images with constrained attributes
58+ "a" , "img" ,
59+ )
60+
61+ // Links: only allow https href and require parseable URLs
62+ p .AllowAttrs ("href" ).OnElements ("a" )
63+ p .AllowURLSchemes ("https" )
64+ p .RequireParseableURLs (true )
65+ p .RequireNoFollowOnLinks ()
66+ p .RequireNoReferrerOnLinks ()
67+ p .AddTargetBlankToFullyQualifiedLinks ()
68+
69+ // Images: allow only https src and basic descriptive attributes
70+ p .AllowImages ()
71+ p .AllowAttrs ("src" , "alt" , "title" ).OnElements ("img" )
72+
73+ policy = p
74+ })
5275}
5376
5477func shouldRemoveRune (r rune ) bool {
0 commit comments