Basic xss prevention

This commit is contained in:
Unknwon 2014-10-04 17:15:22 -04:00
parent 6a79b76531
commit 263d409326
6 changed files with 57 additions and 26 deletions

View file

@ -24,6 +24,7 @@ github.com/macaron-contrib/session =
github.com/macaron-contrib/toolbox = commit:57127bcc89 github.com/macaron-contrib/toolbox = commit:57127bcc89
github.com/mattn/go-sqlite3 = commit:a80c27ba33 github.com/mattn/go-sqlite3 = commit:a80c27ba33
github.com/nfnt/resize = commit:581d15cb53 github.com/nfnt/resize = commit:581d15cb53
github.com/russross/blackfriday =
github.com/saintfish/chardet = commit:3af4cd4741 github.com/saintfish/chardet = commit:3af4cd4741
[res] [res]

View file

@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
) )
const APP_VER = "0.5.4.1003 Beta" const APP_VER = "0.5.4.1004 Beta"
func init() { func init() {
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())

View file

@ -23,6 +23,7 @@ import (
"github.com/Unknwon/cae/zip" "github.com/Unknwon/cae/zip"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/git" "github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process" "github.com/gogits/gogs/modules/process"
@ -48,7 +49,7 @@ var (
) )
var ( var (
DescriptionPattern = regexp.MustCompile(`https?://\S+`) DescPattern = regexp.MustCompile(`https?://\S+`)
) )
func LoadRepoConfig() { func LoadRepoConfig() {
@ -181,7 +182,7 @@ func (repo *Repository) DescriptionHtml() template.HTML {
ss := html.EscapeString(s) ss := html.EscapeString(s)
return fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, ss, ss) return fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, ss, ss)
} }
return template.HTML(DescriptionPattern.ReplaceAllStringFunc(repo.Description, sanitize)) return template.HTML(DescPattern.ReplaceAllStringFunc(base.XSSString(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.

View file

@ -13,7 +13,8 @@ import (
"regexp" "regexp"
"strings" "strings"
"github.com/gogits/gfm" "github.com/russross/blackfriday"
"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
) )
@ -74,7 +75,7 @@ func IsReadmeFile(name string) bool {
} }
type CustomRender struct { type CustomRender struct {
gfm.Renderer blackfriday.Renderer
urlPrefix string urlPrefix string
} }
@ -154,39 +155,40 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
func RenderRawMarkdown(body []byte, urlPrefix string) []byte { func RenderRawMarkdown(body []byte, urlPrefix string) []byte {
htmlFlags := 0 htmlFlags := 0
// htmlFlags |= gfm.HTML_USE_XHTML // htmlFlags |= blackfriday.HTML_USE_XHTML
// htmlFlags |= gfm.HTML_USE_SMARTYPANTS // htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
// htmlFlags |= gfm.HTML_SMARTYPANTS_FRACTIONS // htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS
// htmlFlags |= gfm.HTML_SMARTYPANTS_LATEX_DASHES // htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES
// htmlFlags |= gfm.HTML_SKIP_HTML // htmlFlags |= blackfriday.HTML_SKIP_HTML
htmlFlags |= gfm.HTML_SKIP_STYLE htmlFlags |= blackfriday.HTML_SKIP_STYLE
htmlFlags |= gfm.HTML_SKIP_SCRIPT // htmlFlags |= blackfriday.HTML_SKIP_SCRIPT
htmlFlags |= gfm.HTML_GITHUB_BLOCKCODE // htmlFlags |= blackfriday.HTML_GITHUB_BLOCKCODE
htmlFlags |= gfm.HTML_OMIT_CONTENTS htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
// htmlFlags |= gfm.HTML_COMPLETE_PAGE // htmlFlags |= blackfriday.HTML_COMPLETE_PAGE
renderer := &CustomRender{ renderer := &CustomRender{
Renderer: gfm.HtmlRenderer(htmlFlags, "", ""), Renderer: blackfriday.HtmlRenderer(htmlFlags, "", ""),
urlPrefix: urlPrefix, urlPrefix: urlPrefix,
} }
// set up the parser // set up the parser
extensions := 0 extensions := 0
extensions |= gfm.EXTENSION_NO_INTRA_EMPHASIS extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS
extensions |= gfm.EXTENSION_TABLES extensions |= blackfriday.EXTENSION_TABLES
extensions |= gfm.EXTENSION_FENCED_CODE extensions |= blackfriday.EXTENSION_FENCED_CODE
extensions |= gfm.EXTENSION_AUTOLINK extensions |= blackfriday.EXTENSION_AUTOLINK
extensions |= gfm.EXTENSION_STRIKETHROUGH extensions |= blackfriday.EXTENSION_STRIKETHROUGH
extensions |= gfm.EXTENSION_HARD_LINE_BREAK extensions |= blackfriday.EXTENSION_HARD_LINE_BREAK
extensions |= gfm.EXTENSION_SPACE_HEADERS extensions |= blackfriday.EXTENSION_SPACE_HEADERS
extensions |= gfm.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK extensions |= blackfriday.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK
body = gfm.Markdown(body, renderer, extensions) body = blackfriday.Markdown(body, renderer, extensions)
return body return body
} }
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)
return body return body
} }

View file

@ -14,6 +14,7 @@ import (
"hash" "hash"
"html/template" "html/template"
"math" "math"
"regexp"
"strings" "strings"
"time" "time"
@ -446,3 +447,29 @@ 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&#x0D;]*:`), 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)))
}

View file

@ -1 +1 @@
0.5.4.1003 Beta 0.5.4.1004 Beta