Skip to content

Commit

Permalink
Avoid XSS when opening a broken image due to unescaped ServerError in…
Browse files Browse the repository at this point in the history
… proxy handler

Creating an RSS feed item with the inline description containing an `<img>` tag
with a `srcset` attribute pointing to an invalid URL like
`http:a<script>alert(1)</script>`, we can coerce the proxy handler into an error
condition where the invalid URL is returned unescaped and in full.

This results in JavaScript execution on the Miniflux instance as soon as the
user is convinced to open the broken image.
  • Loading branch information
fguillot committed Mar 13, 2023
1 parent b46b5df commit eb95085
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 1 deletion.
2 changes: 2 additions & 0 deletions http/response/html/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func ServerError(w http.ResponseWriter, r *http.Request, err error) {

builder := response.New(w, r)
builder.WithStatus(http.StatusInternalServerError)
builder.WithHeader("Content-Security-Policy", `default-src 'self'`)
builder.WithHeader("Content-Type", "text/html; charset=utf-8")
builder.WithHeader("Cache-Control", "no-cache, max-age=0, must-revalidate, no-store")
builder.WithBody(err)
Expand All @@ -38,6 +39,7 @@ func BadRequest(w http.ResponseWriter, r *http.Request, err error) {

builder := response.New(w, r)
builder.WithStatus(http.StatusBadRequest)
builder.WithHeader("Content-Security-Policy", `default-src 'self'`)
builder.WithHeader("Content-Type", "text/html; charset=utf-8")
builder.WithHeader("Cache-Control", "no-cache, max-age=0, must-revalidate, no-store")
builder.WithBody(err)
Expand Down
3 changes: 2 additions & 1 deletion ui/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) {

resp, err := clt.Do(req)
if err != nil {
html.ServerError(w, r, err)
logger.Error(`[Proxy] Unable to initialize HTTP client: %v`, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
defer resp.Body.Close()
Expand Down

0 comments on commit eb95085

Please sign in to comment.