summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Frédéric Guillot <f@miniflux.net> 2023-03-12 22:15:43 -0700
committerGravatar Frédéric Guillot <f@miniflux.net> 2023-03-12 22:36:03 -0700
commiteb9508502c97c1341b8120916e34b260824cc52d (patch)
tree468f3b81c38b11e9695d1bfba52a54ab830bb9be
parentb46b5dfb2aa3a1f5320a7a3420b9186bb8fc655f (diff)
downloadv2-eb9508502c97c1341b8120916e34b260824cc52d.tar.gz
v2-eb9508502c97c1341b8120916e34b260824cc52d.tar.zst
v2-eb9508502c97c1341b8120916e34b260824cc52d.zip
Avoid XSS when opening a broken image due to unescaped ServerError in 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.
-rw-r--r--http/response/html/html.go2
-rw-r--r--ui/proxy.go3
2 files changed, 4 insertions, 1 deletions
diff --git a/http/response/html/html.go b/http/response/html/html.go
index c7bf1faf..3bba07f3 100644
--- a/http/response/html/html.go
+++ b/http/response/html/html.go
@@ -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)
@@ -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)
diff --git a/ui/proxy.go b/ui/proxy.go
index 5dd50697..bffbc939 100644
--- a/ui/proxy.go
+++ b/ui/proxy.go
@@ -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()