diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index a149d7f0400..fa7e6dcd73c 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -1931,3 +1931,21 @@ func TestParseConfigDumpOutput(t *testing.T) {
t.Fatal(err)
}
}
+
+func TestContentSecurityPolicy(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("CONTENT_SECURITY_POLICY", "fonts.googleapis.com fonts.gstatic.com")
+
+ parser := NewParser()
+ opts, err := parser.ParseEnvironmentVariables()
+ if err != nil {
+ t.Fatalf(`Parsing failure: %v`, err)
+ }
+
+ expected := "fonts.googleapis.com fonts.gstatic.com"
+ result := opts.ContentSecurityPolicy()
+
+ if result != expected {
+ t.Fatalf(`Unexpected CONTENT_SECURITY_POLICY value, got %v instead of %v`, result, expected)
+ }
+}
diff --git a/internal/config/options.go b/internal/config/options.go
index abbaf84934e..30da1e98b4f 100644
--- a/internal/config/options.go
+++ b/internal/config/options.go
@@ -83,6 +83,7 @@ const (
defaultWatchdog = true
defaultInvidiousInstance = "yewtu.be"
defaultWebAuthn = false
+ defaultContentSecurityPolicy = ""
)
var defaultHTTPClientUserAgent = "Mozilla/5.0 (compatible; Miniflux/" + version.Version + "; +https://miniflux.app)"
@@ -165,6 +166,7 @@ type Options struct {
invidiousInstance string
proxyPrivateKey []byte
webAuthn bool
+ contentSecurityPolicy string
}
// NewOptions returns Options with default values.
@@ -241,6 +243,7 @@ func NewOptions() *Options {
invidiousInstance: defaultInvidiousInstance,
proxyPrivateKey: randomKey,
webAuthn: defaultWebAuthn,
+ contentSecurityPolicy: defaultContentSecurityPolicy,
}
}
@@ -607,6 +610,11 @@ func (o *Options) WebAuthn() bool {
return o.webAuthn
}
+// ContentSecurityPolicy returns value for Content-Security-Policy meta tag.
+func (o *Options) ContentSecurityPolicy() string {
+ return o.contentSecurityPolicy
+}
+
// SortedOptions returns options as a list of key value pairs, sorted by keys.
func (o *Options) SortedOptions(redactSecret bool) []*Option {
var keyValues = map[string]interface{}{
@@ -682,6 +690,7 @@ func (o *Options) SortedOptions(redactSecret bool) []*Option {
"WORKER_POOL_SIZE": o.workerPoolSize,
"YOUTUBE_EMBED_URL_OVERRIDE": o.youTubeEmbedUrlOverride,
"WEBAUTHN": o.webAuthn,
+ "CONTENT_SECURITY_POLICY": o.contentSecurityPolicy,
}
keys := make([]string, 0, len(keyValues))
diff --git a/internal/config/parser.go b/internal/config/parser.go
index d64d67c7fb4..b515303950e 100644
--- a/internal/config/parser.go
+++ b/internal/config/parser.go
@@ -248,6 +248,8 @@ func (p *Parser) parseLines(lines []string) (err error) {
p.opts.proxyPrivateKey = parseBytes(value, randomKey)
case "WEBAUTHN":
p.opts.webAuthn = parseBool(value, defaultWebAuthn)
+ case "CONTENT_SECURITY_POLICY":
+ p.opts.contentSecurityPolicy = parseString(value, defaultContentSecurityPolicy)
}
}
diff --git a/internal/template/templates/common/layout.html b/internal/template/templates/common/layout.html
index 3076ec18dd4..e490950719b 100644
--- a/internal/template/templates/common/layout.html
+++ b/internal/template/templates/common/layout.html
@@ -36,7 +36,7 @@
{{ if and .user .user.Stylesheet }}
{{ $stylesheetNonce := nonce }}
-
+
{{ else }}
diff --git a/internal/ui/view/view.go b/internal/ui/view/view.go
index 077340b5ae3..3818b0ee24b 100644
--- a/internal/ui/view/view.go
+++ b/internal/ui/view/view.go
@@ -46,5 +46,6 @@ func New(tpl *template.Engine, r *http.Request, sess *session.Session) *View {
b.params["sw_js_checksum"] = static.JavascriptBundleChecksums["service-worker"]
b.params["webauthn_js_checksum"] = static.JavascriptBundleChecksums["webauthn"]
b.params["webAuthnEnabled"] = config.Opts.WebAuthn()
+ b.params["contentSecurityPolicy"] = config.Opts.ContentSecurityPolicy()
return b
}
diff --git a/miniflux.1 b/miniflux.1
index 7bf9ebd154f..c5f36178d06 100644
--- a/miniflux.1
+++ b/miniflux.1
@@ -520,6 +520,11 @@ Default is randomly generated at startup\&.
Enable or disable WebAuthn/Passkey authentication\&.
.br
Default is disabled\&.
+.B CONTENT_SECURITY_POLICY
+Set custom domain list for Content-Security-Policy meta tag\&.
+.br
+Default is empty\&.
+.TP
.SH AUTHORS
.P