3 Commits

Author SHA1 Message Date
e3cee5b94c doc: changelog update 2017-08-13 18:27:04 +12:00
e4cf02cde7 restructure error handling to prevent reflected XSS 2017-08-13 18:25:58 +12:00
06e5b4ddf9 bump version to 3.0.1 2017-08-13 18:07:29 +12:00
6 changed files with 32 additions and 14 deletions

View File

@@ -2,7 +2,7 @@
# Makefile for YATWiki3 # Makefile for YATWiki3
# #
VERSION:=3.0.1 VERSION:=3.0.2
SOURCES:=Makefile \ SOURCES:=Makefile \
static \ static \

View File

@@ -35,6 +35,9 @@ This package can be installed via go get: `go get code.ivysaur.me/yatwiki`
=CHANGELOG= =CHANGELOG=
2017-08-11 3.0.2
- Fix an issue with XSS prevention for web browsers other than Chrome
2017-08-11 3.0.1 2017-08-11 3.0.1
- Feature: New `TrustXForwardedFor` config option for usage behind reverse proxies - Feature: New `TrustXForwardedFor` config option for usage behind reverse proxies
- Fix an issue with article titles containing `+` - Fix an issue with article titles containing `+`

View File

@@ -17,7 +17,9 @@ type pageTemplateOptions struct {
LoadCodeResources bool LoadCodeResources bool
DefaultPage string DefaultPage string
AllowDownload bool AllowDownload bool
SessionMessage template.HTML SessionMessage string
PageNotExistsError bool
PageNotExistsTarget string
} }
func DefaultPageTemplateOptions(opts *ServerOptions) *pageTemplateOptions { func DefaultPageTemplateOptions(opts *ServerOptions) *pageTemplateOptions {
@@ -105,6 +107,12 @@ function els(e,s){ // no js exec in innerHTML
{{end}} {{end}}
</div> </div>
<div class="content"> <div class="content">
{{if .PageNotExistsError}}
<div class="info">
No such article exists.
<a href="{{.BaseURL}}modify/{{.PageNotExistsTarget | pathcomponent}}">Click here</a> to create it.
</div>
{{end}}
{{if len .SessionMessage}} {{if len .SessionMessage}}
<div class="info">{{.SessionMessage}}</div> <div class="info">{{.SessionMessage}}</div>
{{end}} {{end}}

View File

@@ -8,12 +8,8 @@ import (
"time" "time"
) )
func (this *WikiServer) noSuchArticleError(title string) template.HTML { func (this *WikiServer) serveErrorMessage(w http.ResponseWriter, err error) {
return template.HTML(`No such article exists. <a href="` + this.opts.ExpectBaseURL + `modify/` + template.HTMLEscapeString(url.PathEscape(title)) + `">Click here</a> to create it.`) this.serveErrorText(w, err.Error())
}
func (this *WikiServer) serveErrorMessage(w http.ResponseWriter, message error) {
this.serveErrorHTMLMessage(w, template.HTML(template.HTMLEscapeString(message.Error())))
} }
func (this *WikiServer) serveInternalError(w http.ResponseWriter, r *http.Request, e error) { func (this *WikiServer) serveInternalError(w http.ResponseWriter, r *http.Request, e error) {
@@ -21,8 +17,12 @@ func (this *WikiServer) serveInternalError(w http.ResponseWriter, r *http.Reques
http.Error(w, "An internal error occurred. Please ask an administrator to check the log file.", 500) http.Error(w, "An internal error occurred. Please ask an administrator to check the log file.", 500)
} }
func (this *WikiServer) serveErrorHTMLMessage(w http.ResponseWriter, msg template.HTML) { func (this *WikiServer) serveErrorText(w http.ResponseWriter, msg string) {
this.serveRedirect(w, this.opts.ExpectBaseURL+"view/"+url.PathEscape(this.opts.DefaultPage)+"?error="+url.QueryEscape(string(msg))) this.serveRedirect(w, this.opts.ExpectBaseURL+"view/"+url.PathEscape(this.opts.DefaultPage)+"?error="+url.QueryEscape(msg))
}
func (this *WikiServer) serveNoSuchArticle(w http.ResponseWriter, lookingFor string) {
this.serveRedirect(w, this.opts.ExpectBaseURL+"view/"+url.PathEscape(this.opts.DefaultPage)+"?notfound="+url.QueryEscape(lookingFor))
} }
func (this *WikiServer) serveRedirect(w http.ResponseWriter, location string) { func (this *WikiServer) serveRedirect(w http.ResponseWriter, location string) {
@@ -32,7 +32,14 @@ func (this *WikiServer) serveRedirect(w http.ResponseWriter, location string) {
func (this *WikiServer) servePageResponse(w http.ResponseWriter, r *http.Request, pto *pageTemplateOptions) { func (this *WikiServer) servePageResponse(w http.ResponseWriter, r *http.Request, pto *pageTemplateOptions) {
w.WriteHeader(200) w.WriteHeader(200)
pto.SessionMessage = template.HTML(r.URL.Query().Get("error")) // FIXME reflected XSS (although Chrome automatically blocks it..)
if noSuchArticleTarget, ok := r.URL.Query()["notfound"]; ok {
pto.PageNotExistsError = true
pto.PageNotExistsTarget = noSuchArticleTarget[0]
} else {
pto.SessionMessage = r.URL.Query().Get("error")
}
err := this.pageTmp.Execute(w, pto) err := this.pageTmp.Execute(w, pto)
if err != nil { if err != nil {

View File

@@ -12,7 +12,7 @@ func (this *WikiServer) routeHistory(w http.ResponseWriter, r *http.Request, art
revs, err := this.db.GetRevisionHistory(articleTitle) revs, err := this.db.GetRevisionHistory(articleTitle)
if err != nil { if err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
this.serveErrorHTMLMessage(w, this.noSuchArticleError(articleTitle)) this.serveNoSuchArticle(w, articleTitle)
return return
} }
@@ -21,7 +21,7 @@ func (this *WikiServer) routeHistory(w http.ResponseWriter, r *http.Request, art
} }
if len(revs) == 0 { if len(revs) == 0 {
this.serveErrorHTMLMessage(w, this.noSuchArticleError(articleTitle)) this.serveNoSuchArticle(w, articleTitle)
return return
} }

View File

@@ -19,7 +19,7 @@ func (this *WikiServer) routeView(w http.ResponseWriter, r *http.Request, articl
return return
} }
this.serveErrorHTMLMessage(w, this.noSuchArticleError(articleTitle)) this.serveNoSuchArticle(w, articleTitle)
return return
} }
this.serveErrorMessage(w, err) this.serveErrorMessage(w, err)