From 6140d82eb25d5b66382b075c3fe9527381c661a9 Mon Sep 17 00:00:00 2001 From: Dmitry Verkhoturov Date: Sun, 20 Oct 2024 21:46:26 +0100 Subject: [PATCH] Fix CSP img-src directive to allow everything without proxy Change the default img-src value to "*" and sets it to "'self'" when image proxy is enabled. The previous state was inversion of this logic which was wrong. --- backend/app/rest/api/rest.go | 4 ++-- backend/app/rest/api/rest_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/backend/app/rest/api/rest.go b/backend/app/rest/api/rest.go index 9f38e45b..293e793d 100644 --- a/backend/app/rest/api/rest.go +++ b/backend/app/rest/api/rest.go @@ -624,9 +624,9 @@ func cacheControl(expiration time.Duration, version string) func(http.Handler) h func securityHeadersMiddleware(imageProxyEnabled bool, allowedAncestors []string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - imgSrc := "'self'" + imgSrc := "*" if imageProxyEnabled { - imgSrc = "*" + imgSrc = "'self'" } frameAncestors := "*" if len(allowedAncestors) > 0 { diff --git a/backend/app/rest/api/rest_test.go b/backend/app/rest/api/rest_test.go index 63f19e34..fb1f7ace 100644 --- a/backend/app/rest/api/rest_test.go +++ b/backend/app/rest/api/rest_test.go @@ -345,6 +345,31 @@ func TestRest_frameAncestors(t *testing.T) { assert.Contains(t, resp.Header.Get("Content-Security-Policy"), "frame-ancestors *;") } +// check CSP, img-src should be 'self' with proxy enabled and * without it +func TestRest_securityHeaders(t *testing.T) { + ts, _, teardown := startupT(t) + + // with proxy disabled + client := http.Client{} + resp, err := client.Get(ts.URL + "/web/index.html") + require.NoError(t, err) + defer resp.Body.Close() + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Contains(t, resp.Header.Get("Content-Security-Policy"), "img-src *;") + teardown() + + // check CSP with proxy enabled + ts, _, teardown = startupT(t, func(srv *Rest) { + srv.ExternalImageProxy = true + }) + defer teardown() + resp, err = client.Get(ts.URL + "/web/index.html") + require.NoError(t, err) + defer resp.Body.Close() + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Contains(t, resp.Header.Get("Content-Security-Policy"), "img-src 'self';") +} + func TestRest_subscribersOnly(t *testing.T) { paidSubUser := &token.User{} paidSubUser.SetPaidSub(true)