restructure error handling to prevent reflected XSS
This commit is contained in:
parent
06e5b4ddf9
commit
e4cf02cde7
@ -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}}
|
||||||
|
25
rErrors.go
25
rErrors.go
@ -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 {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
rView.go
2
rView.go
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user