diff --git a/internal/middleware/extraheaders.go b/internal/middleware/extraheaders.go index be7591be1..064e85cca 100644 --- a/internal/middleware/extraheaders.go +++ b/internal/middleware/extraheaders.go @@ -54,19 +54,16 @@ func BuildContentSecurityPolicy() string { // Debug is enabled, allow // serving things from localhost // as well (regardless of port). - policy += " localhost:*" + policy += " localhost:* ws://localhost:*" } + // Disallow object-src as recommended https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/object-src + policy += "; object-src 'none'" + s3Endpoint := config.GetStorageS3Endpoint() - if s3Endpoint == "" { - // S3 not configured, - // default policy is OK. - return policy - } - - if config.GetStorageS3Proxy() { - // S3 is configured in proxy - // mode, default policy is OK. + if s3Endpoint == "" || config.GetStorageS3Proxy() { + // S3 not configured or in proxy mode, just allow images from self and blob: + policy += "; img-src 'self' blob:" return policy } @@ -88,7 +85,7 @@ func BuildContentSecurityPolicy() string { // handle any redirects from the fileserver to object storage. // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/img-src - policy += "; img-src 'self' " + s3EndpointURLStr + policy += "; img-src 'self' blob: " + s3EndpointURLStr // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/media-src policy += "; media-src 'self' " + s3EndpointURLStr diff --git a/internal/middleware/middleware_test.go b/internal/middleware/middleware_test.go index 81c7c0be1..29376304e 100644 --- a/internal/middleware/middleware_test.go +++ b/internal/middleware/middleware_test.go @@ -38,55 +38,55 @@ type cspTest struct { s3Endpoint: "", s3Proxy: false, s3Secure: false, - expected: "default-src 'self'", + expected: "default-src 'self'; object-src 'none'; img-src 'self' blob:", }, { s3Endpoint: "some-bucket-provider.com", s3Proxy: false, s3Secure: true, - expected: "default-src 'self'; img-src 'self' https://some-bucket-provider.com; media-src 'self' https://some-bucket-provider.com", + expected: "default-src 'self'; object-src 'none'; img-src 'self' blob: https://some-bucket-provider.com; media-src 'self' https://some-bucket-provider.com", }, { s3Endpoint: "some-bucket-provider.com:6969", s3Proxy: false, s3Secure: true, - expected: "default-src 'self'; img-src 'self' https://some-bucket-provider.com:6969; media-src 'self' https://some-bucket-provider.com:6969", + expected: "default-src 'self'; object-src 'none'; img-src 'self' blob: https://some-bucket-provider.com:6969; media-src 'self' https://some-bucket-provider.com:6969", }, { s3Endpoint: "some-bucket-provider.com:6969", s3Proxy: false, s3Secure: false, - expected: "default-src 'self'; img-src 'self' http://some-bucket-provider.com:6969; media-src 'self' http://some-bucket-provider.com:6969", + expected: "default-src 'self'; object-src 'none'; img-src 'self' blob: http://some-bucket-provider.com:6969; media-src 'self' http://some-bucket-provider.com:6969", }, { s3Endpoint: "s3.nl-ams.scw.cloud", s3Proxy: false, s3Secure: true, - expected: "default-src 'self'; img-src 'self' https://s3.nl-ams.scw.cloud; media-src 'self' https://s3.nl-ams.scw.cloud", + expected: "default-src 'self'; object-src 'none'; img-src 'self' blob: https://s3.nl-ams.scw.cloud; media-src 'self' https://s3.nl-ams.scw.cloud", }, { s3Endpoint: "some-bucket-provider.com", s3Proxy: true, s3Secure: true, - expected: "default-src 'self'", + expected: "default-src 'self'; object-src 'none'; img-src 'self' blob:", }, { s3Endpoint: "some-bucket-provider.com:6969", s3Proxy: true, s3Secure: true, - expected: "default-src 'self'", + expected: "default-src 'self'; object-src 'none'; img-src 'self' blob:", }, { s3Endpoint: "some-bucket-provider.com:6969", s3Proxy: true, s3Secure: true, - expected: "default-src 'self'", + expected: "default-src 'self'; object-src 'none'; img-src 'self' blob:", }, { s3Endpoint: "s3.nl-ams.scw.cloud", s3Proxy: true, s3Secure: true, - expected: "default-src 'self'", + expected: "default-src 'self'; object-src 'none'; img-src 'self' blob:", }, } { config.SetStorageS3Endpoint(test.s3Endpoint)