| @@ -7,7 +7,6 @@ package models | |||||
| import ( | import ( | ||||
| "errors" | "errors" | ||||
| "fmt" | "fmt" | ||||
| "html" | |||||
| "html/template" | "html/template" | ||||
| "io/ioutil" | "io/ioutil" | ||||
| "os" | "os" | ||||
| @@ -218,11 +217,9 @@ func (repo *Repository) HasAccess(uname string) bool { | |||||
| // DescriptionHtml does special handles to description and return HTML string. | // DescriptionHtml does special handles to description and return HTML string. | ||||
| func (repo *Repository) DescriptionHtml() template.HTML { | func (repo *Repository) DescriptionHtml() template.HTML { | ||||
| sanitize := func(s string) string { | sanitize := func(s string) string { | ||||
| // TODO(nuss-justin): Improve sanitization. Strip all tags? | |||||
| ss := html.EscapeString(s) | |||||
| return fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, ss, ss) | |||||
| return fmt.Sprintf(`<a href="%[1]s" target="_blank">%[1]s</a>`, s) | |||||
| } | } | ||||
| return template.HTML(DescPattern.ReplaceAllStringFunc(base.XSSString(repo.Description), sanitize)) | |||||
| return template.HTML(DescPattern.ReplaceAllStringFunc(base.Sanitizer.Sanitize(repo.Description), sanitize)) | |||||
| } | } | ||||
| // IsRepositoryExist returns true if the repository with given name under user has already existed. | // IsRepositoryExist returns true if the repository with given name under user has already existed. | ||||
| @@ -212,7 +212,7 @@ func RenderRawMarkdown(body []byte, urlPrefix string) []byte { | |||||
| func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte { | func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte { | ||||
| body := RenderSpecialLink(rawBytes, urlPrefix) | body := RenderSpecialLink(rawBytes, urlPrefix) | ||||
| body = RenderRawMarkdown(body, urlPrefix) | body = RenderRawMarkdown(body, urlPrefix) | ||||
| body = XSS(body) | |||||
| body = Sanitizer.SanitizeBytes(body) | |||||
| return body | return body | ||||
| } | } | ||||
| @@ -13,7 +13,6 @@ import ( | |||||
| "strings" | "strings" | ||||
| "time" | "time" | ||||
| "github.com/microcosm-cc/bluemonday" | |||||
| "golang.org/x/net/html/charset" | "golang.org/x/net/html/charset" | ||||
| "golang.org/x/text/transform" | "golang.org/x/text/transform" | ||||
| @@ -21,11 +20,8 @@ import ( | |||||
| "github.com/gogits/gogs/modules/setting" | "github.com/gogits/gogs/modules/setting" | ||||
| ) | ) | ||||
| // FIXME: use me to Markdown API renders | |||||
| var p = bluemonday.UGCPolicy() | |||||
| func Str2html(raw string) template.HTML { | func Str2html(raw string) template.HTML { | ||||
| return template.HTML(p.Sanitize(raw)) | |||||
| return template.HTML(Sanitizer.Sanitize(raw)) | |||||
| } | } | ||||
| func Range(l int) []int { | func Range(l int) []int { | ||||
| @@ -15,17 +15,19 @@ import ( | |||||
| "hash" | "hash" | ||||
| "html/template" | "html/template" | ||||
| "math" | "math" | ||||
| "regexp" | |||||
| "strings" | "strings" | ||||
| "time" | "time" | ||||
| "github.com/Unknwon/com" | "github.com/Unknwon/com" | ||||
| "github.com/Unknwon/i18n" | "github.com/Unknwon/i18n" | ||||
| "github.com/microcosm-cc/bluemonday" | |||||
| "github.com/gogits/gogs/modules/avatar" | "github.com/gogits/gogs/modules/avatar" | ||||
| "github.com/gogits/gogs/modules/setting" | "github.com/gogits/gogs/modules/setting" | ||||
| ) | ) | ||||
| var Sanitizer = bluemonday.UGCPolicy() | |||||
| // Encode string to md5 hex value. | // Encode string to md5 hex value. | ||||
| func EncodeMd5(str string) string { | func EncodeMd5(str string) string { | ||||
| m := md5.New() | m := md5.New() | ||||
| @@ -473,29 +475,3 @@ func DateFormat(t time.Time, format string) string { | |||||
| format = replacer.Replace(format) | format = replacer.Replace(format) | ||||
| return t.Format(format) | return t.Format(format) | ||||
| } | } | ||||
| type xssFilter struct { | |||||
| reg *regexp.Regexp | |||||
| repl []byte | |||||
| } | |||||
| var ( | |||||
| whiteSpace = []byte(" ") | |||||
| xssFilters = []xssFilter{ | |||||
| {regexp.MustCompile(`\ [ONon]\w*=["]*`), whiteSpace}, | |||||
| {regexp.MustCompile(`<[SCRIPTscript]{6}`), whiteSpace}, | |||||
| {regexp.MustCompile(`=[` + "`" + `'"]*[JAVASCRIPTjavascript \t\0
]*:`), whiteSpace}, | |||||
| } | |||||
| ) | |||||
| // XSS goes through all the XSS filters to make user input content as safe as possible. | |||||
| func XSS(in []byte) []byte { | |||||
| for _, filter := range xssFilters { | |||||
| in = filter.reg.ReplaceAll(in, filter.repl) | |||||
| } | |||||
| return in | |||||
| } | |||||
| func XSSString(in string) string { | |||||
| return string(XSS([]byte(in))) | |||||
| } | |||||