Browse Source

fix: avoid YouTube error 153 for embed iframes

Add the attribute `referrerpolicy="strict-origin-when-cross-origin"` to
YouTube iframes.

Superseded PR #3862
Frédéric Guillot 4 months ago
parent
commit
4892e04e9b

+ 1 - 3
internal/reader/rewrite/content_rewrite_functions.go

@@ -286,9 +286,7 @@ func getYoutubVideoIDFromURL(entryURL string) string {
 }
 
 func buildVideoPlayerIframe(absoluteVideoURL string) string {
-	// Note: the referrerpolicy seems to be required to avoid YouTube error 153 video player configuration error
-	// See https://developers.google.com/youtube/terms/required-minimum-functionality#embedded-player-api-client-identity
-	return `<iframe width="650" height="350" frameborder="0" src="` + absoluteVideoURL + `" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe>`
+	return `<iframe width="650" height="350" frameborder="0" src="` + absoluteVideoURL + `" allowfullscreen></iframe>`
 }
 
 func addVideoPlayerIframe(absoluteVideoURL, entryContent string) string {

+ 18 - 18
internal/reader/rewrite/content_rewrite_test.go

@@ -72,7 +72,7 @@ func TestRewriteYoutubeVideoLink(t *testing.T) {
 	controlEntry := &model.Entry{
 		URL:     "https://www.youtube.com/watch?v=1234",
 		Title:   `A title`,
-		Content: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/1234" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video Description`,
+		Content: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/1234" allowfullscreen></iframe><br>Video Description`,
 	}
 	testEntry := &model.Entry{
 		URL:     "https://www.youtube.com/watch?v=1234",
@@ -92,7 +92,7 @@ func TestRewriteYoutubeShortLink(t *testing.T) {
 	controlEntry := &model.Entry{
 		URL:     "https://www.youtube.com/shorts/1LUWKWZkPjo",
 		Title:   `A title`,
-		Content: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/1LUWKWZkPjo" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video Description`,
+		Content: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/1LUWKWZkPjo" allowfullscreen></iframe><br>Video Description`,
 	}
 	testEntry := &model.Entry{
 		URL:     "https://www.youtube.com/shorts/1LUWKWZkPjo",
@@ -140,7 +140,7 @@ func TestRewriteYoutubeLinkAndCustomEmbedURL(t *testing.T) {
 	controlEntry := &model.Entry{
 		URL:     "https://www.youtube.com/watch?v=1234",
 		Title:   `A title`,
-		Content: `<iframe width="650" height="350" frameborder="0" src="https://invidious.custom/embed/1234" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video Description`,
+		Content: `<iframe width="650" height="350" frameborder="0" src="https://invidious.custom/embed/1234" allowfullscreen></iframe><br>Video Description`,
 	}
 	testEntry := &model.Entry{
 		URL:     "https://www.youtube.com/watch?v=1234",
@@ -159,7 +159,7 @@ func TestRewriteYoutubeVideoLinkUsingInvidious(t *testing.T) {
 	controlEntry := &model.Entry{
 		URL:     "https://www.youtube.com/watch?v=1234",
 		Title:   `A title`,
-		Content: `<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/1234" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video Description`,
+		Content: `<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/1234" allowfullscreen></iframe><br>Video Description`,
 	}
 	testEntry := &model.Entry{
 		URL:     "https://www.youtube.com/watch?v=1234",
@@ -179,7 +179,7 @@ func TestRewriteYoutubeShortLinkUsingInvidious(t *testing.T) {
 	controlEntry := &model.Entry{
 		URL:     "https://www.youtube.com/shorts/1LUWKWZkPjo",
 		Title:   `A title`,
-		Content: `<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/1LUWKWZkPjo" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video Description`,
+		Content: `<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/1LUWKWZkPjo" allowfullscreen></iframe><br>Video Description`,
 	}
 	testEntry := &model.Entry{
 		URL:     "https://www.youtube.com/shorts/1LUWKWZkPjo",
@@ -199,16 +199,16 @@ func TestAddYoutubeVideoFromId(t *testing.T) {
 
 	scenarios := map[string]string{
 		// Test with single YouTube ID
-		`Some content with youtube ID <script type="text/javascript" data-reactid="6">window.__APOLLO_STATE__ = {youtube_id: "9uASADiYe_8"}</script>`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/9uASADiYe_8" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Some content with youtube ID <script type="text/javascript" data-reactid="6">window.__APOLLO_STATE__ = {youtube_id: "9uASADiYe_8"}</script>`,
+		`Some content with youtube ID <script type="text/javascript" data-reactid="6">window.__APOLLO_STATE__ = {youtube_id: "9uASADiYe_8"}</script>`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/9uASADiYe_8" allowfullscreen></iframe><br>Some content with youtube ID <script type="text/javascript" data-reactid="6">window.__APOLLO_STATE__ = {youtube_id: "9uASADiYe_8"}</script>`,
 
 		// Test with multiple YouTube IDs
-		`Content with youtube_id: "dQw4w9WgXcQ" and youtube_id: "jNQXAC9IVRw"`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br><iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/jNQXAC9IVRw" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Content with youtube_id: "dQw4w9WgXcQ" and youtube_id: "jNQXAC9IVRw"`,
+		`Content with youtube_id: "dQw4w9WgXcQ" and youtube_id: "jNQXAC9IVRw"`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br><iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/jNQXAC9IVRw" allowfullscreen></iframe><br>Content with youtube_id: "dQw4w9WgXcQ" and youtube_id: "jNQXAC9IVRw"`,
 
 		// Test with YouTube ID using equals sign
-		`Some content with youtube_id = "dQw4w9WgXcQ"`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Some content with youtube_id = "dQw4w9WgXcQ"`,
+		`Some content with youtube_id = "dQw4w9WgXcQ"`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Some content with youtube_id = "dQw4w9WgXcQ"`,
 
 		// Test with spaces around delimiters
-		`Some content with youtube_id : "dQw4w9WgXcQ"`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Some content with youtube_id : "dQw4w9WgXcQ"`,
+		`Some content with youtube_id : "dQw4w9WgXcQ"`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Some content with youtube_id : "dQw4w9WgXcQ"`,
 
 		// Test with YouTube ID without quotes (regex requires quotes)
 		`Some content with youtube_id: dQw4w9WgXcQ and more`: `Some content with youtube_id: dQw4w9WgXcQ and more`,
@@ -245,7 +245,7 @@ func TestAddYoutubeVideoFromIdWithCustomEmbedURL(t *testing.T) {
 	}
 
 	input := `Some content with youtube_id: "dQw4w9WgXcQ"`
-	expected := `<iframe width="650" height="350" frameborder="0" src="https://invidious.custom/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Some content with youtube_id: "dQw4w9WgXcQ"`
+	expected := `<iframe width="650" height="350" frameborder="0" src="https://invidious.custom/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Some content with youtube_id: "dQw4w9WgXcQ"`
 
 	actual := addYoutubeVideoFromId(input)
 	if actual != expected {
@@ -260,35 +260,35 @@ func TestAddInvidiousVideo(t *testing.T) {
 		// Test with various Invidious instances
 		"https://invidious.io/watch?v=dQw4w9WgXcQ": {
 			"Some video content",
-			`<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Some video content`,
+			`<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Some video content`,
 		},
 		"https://yewtu.be/watch?v=jNQXAC9IVRw": {
 			"Another video description",
-			`<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/jNQXAC9IVRw" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Another video description`,
+			`<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/jNQXAC9IVRw" allowfullscreen></iframe><br>Another video description`,
 		},
 		"http://invidious.snopyta.org/watch?v=dQw4w9WgXcQ": {
 			"HTTP instance test",
-			`<iframe width="650" height="350" frameborder="0" src="https://invidious.snopyta.org/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>HTTP instance test`,
+			`<iframe width="650" height="350" frameborder="0" src="https://invidious.snopyta.org/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>HTTP instance test`,
 		},
 		"https://youtube.com/watch?v=dQw4w9WgXcQ": {
 			"YouTube URL (also matches regex)",
-			`<iframe width="650" height="350" frameborder="0" src="https://youtube.com/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>YouTube URL (also matches regex)`,
+			`<iframe width="650" height="350" frameborder="0" src="https://youtube.com/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>YouTube URL (also matches regex)`,
 		},
 		"https://example.org/watch?v=dQw4w9WgXcQ": {
 			"Any domain with watch pattern",
-			`<iframe width="650" height="350" frameborder="0" src="https://example.org/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Any domain with watch pattern`,
+			`<iframe width="650" height="350" frameborder="0" src="https://example.org/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Any domain with watch pattern`,
 		},
 
 		// Test with query parameters
 		"https://invidious.io/watch?v=dQw4w9WgXcQ&t=30s": {
 			"Video with timestamp",
-			`<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ?t=30s" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video with timestamp`,
+			`<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ?t=30s" allowfullscreen></iframe><br>Video with timestamp`,
 		},
 
 		// Test with more complex query parameters
 		"https://invidious.io/watch?v=dQw4w9WgXcQ&t=30s&autoplay=1": {
 			"Video with multiple parameters",
-			`<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ?autoplay=1&t=30s" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video with multiple parameters`,
+			`<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ?autoplay=1&t=30s" allowfullscreen></iframe><br>Video with multiple parameters`,
 		},
 
 		// Test with non-matching URLs (should return content unchanged)
@@ -308,7 +308,7 @@ func TestAddInvidiousVideo(t *testing.T) {
 		// Test with empty content
 		"https://empty.invidious.io/watch?v=dQw4w9WgXcQ": {
 			"",
-			`<iframe width="650" height="350" frameborder="0" src="https://empty.invidious.io/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>`,
+			`<iframe width="650" height="350" frameborder="0" src="https://empty.invidious.io/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>`,
 		},
 	}
 

+ 30 - 10
internal/reader/sanitizer/sanitizer.go

@@ -45,7 +45,7 @@ var (
 		"h5":         {"id"},
 		"h6":         {"id"},
 		"hr":         {},
-		"iframe":     {"width", "height", "frameborder", "src", "allowfullscreen", "referrerpolicy"},
+		"iframe":     {"width", "height", "frameborder", "src", "allowfullscreen"},
 		"img":        {"alt", "title", "src", "srcset", "sizes", "width", "height", "fetchpriority", "decoding"},
 		"ins":        {},
 		"kbd":        {},
@@ -309,6 +309,7 @@ func sanitizeAttributes(parsedBaseUrl *url.URL, tagName string, attributes []htm
 	attrNames := make([]string, 0, len(attributes))
 	var err error
 	var isAnchorLink bool
+	var isYouTubeEmbed bool
 
 	for _, attribute := range attributes {
 		if !isValidAttribute(tagName, attribute.Key) {
@@ -355,10 +356,16 @@ func sanitizeAttributes(parsedBaseUrl *url.URL, tagName string, attributes []htm
 		if isExternalResourceAttribute(attribute.Key) {
 			switch {
 			case tagName == "iframe":
-				if !isValidIframeSource(attribute.Val) {
+				iframeSourceDomain, trustedIframeDomain := findAllowedIframeSourceDomain(attribute.Val)
+				if !trustedIframeDomain {
 					continue
 				}
+
 				value = rewriteIframeURL(attribute.Val)
+
+				if iframeSourceDomain == "youtube.com" || iframeSourceDomain == "youtube-nocookie.com" {
+					isYouTubeEmbed = true
+				}
 			case tagName == "img" && attribute.Key == "src" && isValidDataAttribute(attribute.Val):
 				value = attribute.Val
 			case tagName == "a" && attribute.Key == "href" && strings.HasPrefix(attribute.Val, "#"):
@@ -387,7 +394,7 @@ func sanitizeAttributes(parsedBaseUrl *url.URL, tagName string, attributes []htm
 	}
 
 	if !isAnchorLink {
-		extraAttrNames, extraHTMLAttributes := getExtraAttributes(tagName, sanitizerOptions)
+		extraAttrNames, extraHTMLAttributes := getExtraAttributes(tagName, isYouTubeEmbed, sanitizerOptions)
 		if len(extraAttrNames) > 0 {
 			attrNames = append(attrNames, extraAttrNames...)
 			htmlAttrs = append(htmlAttrs, extraHTMLAttributes...)
@@ -397,7 +404,7 @@ func sanitizeAttributes(parsedBaseUrl *url.URL, tagName string, attributes []htm
 	return attrNames, strings.Join(htmlAttrs, " ")
 }
 
-func getExtraAttributes(tagName string, sanitizerOptions *SanitizerOptions) ([]string, []string) {
+func getExtraAttributes(tagName string, isYouTubeEmbed bool, sanitizerOptions *SanitizerOptions) ([]string, []string) {
 	switch tagName {
 	case "a":
 		attributeNames := []string{"rel", "referrerpolicy"}
@@ -410,7 +417,20 @@ func getExtraAttributes(tagName string, sanitizerOptions *SanitizerOptions) ([]s
 	case "video", "audio":
 		return []string{"controls"}, []string{"controls"}
 	case "iframe":
-		return []string{"sandbox", "loading"}, []string{`sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"`, `loading="lazy"`}
+		extraAttrNames := []string{}
+		extraHTMLAttributes := []string{}
+
+		// Note: the referrerpolicy seems to be required to avoid YouTube error 153 video player configuration error
+		// See https://developers.google.com/youtube/terms/required-minimum-functionality#embedded-player-api-client-identity
+		if isYouTubeEmbed {
+			extraAttrNames = append(extraAttrNames, "referrerpolicy")
+			extraHTMLAttributes = append(extraHTMLAttributes, `referrerpolicy="strict-origin-when-cross-origin"`)
+		}
+
+		extraAttrNames = append(extraAttrNames, "sandbox", "loading")
+		extraHTMLAttributes = append(extraHTMLAttributes, `sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"`, `loading="lazy"`)
+
+		return extraAttrNames, extraHTMLAttributes
 	case "img":
 		return []string{"loading"}, []string{`loading="lazy"`}
 	default:
@@ -496,22 +516,22 @@ func isBlockedResource(absoluteURL string) bool {
 	return false
 }
 
-func isValidIframeSource(iframeSourceURL string) bool {
+func findAllowedIframeSourceDomain(iframeSourceURL string) (string, bool) {
 	iframeSourceDomain := urllib.DomainWithoutWWW(iframeSourceURL)
 
 	if _, ok := iframeAllowList[iframeSourceDomain]; ok {
-		return true
+		return iframeSourceDomain, true
 	}
 
 	if ytDomain := config.Opts.YouTubeEmbedDomain(); ytDomain != "" && iframeSourceDomain == strings.TrimPrefix(ytDomain, "www.") {
-		return true
+		return iframeSourceDomain, true
 	}
 
 	if invidiousInstance := config.Opts.InvidiousInstance(); invidiousInstance != "" && iframeSourceDomain == strings.TrimPrefix(invidiousInstance, "www.") {
-		return true
+		return iframeSourceDomain, true
 	}
 
-	return false
+	return "", false
 }
 
 func rewriteIframeURL(link string) string {

+ 47 - 7
internal/reader/sanitizer/sanitizer_test.go

@@ -449,7 +449,7 @@ func TestIFrameWithChildElements(t *testing.T) {
 	config.Opts = config.NewConfigOptions()
 
 	input := `<iframe src="https://www.youtube.com/"><p>test</p></iframe>`
-	expected := `<iframe src="https://www.youtube.com/" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
+	expected := `<iframe src="https://www.youtube.com/" referrerpolicy="strict-origin-when-cross-origin" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
 	output := sanitizeHTMLWithDefaultOptions("http://example.com/", input)
 
 	if expected != output {
@@ -808,8 +808,16 @@ func TestEspaceAttributes(t *testing.T) {
 }
 
 func TestReplaceYoutubeURL(t *testing.T) {
+	os.Clearenv()
+
+	var err error
+	config.Opts, err = config.NewConfigParser().ParseEnvironmentVariables()
+	if err != nil {
+		t.Fatalf(`Parsing failure: %v`, err)
+	}
+
 	input := `<iframe src="http://www.youtube.com/embed/test123?version=3&#038;rel=1&#038;fs=1&#038;autohide=2&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent"></iframe>`
-	expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123?version=3&amp;rel=1&amp;fs=1&amp;autohide=2&amp;showsearch=0&amp;showinfo=1&amp;iv_load_policy=1&amp;wmode=transparent" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
+	expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123?version=3&amp;rel=1&amp;fs=1&amp;autohide=2&amp;showsearch=0&amp;showinfo=1&amp;iv_load_policy=1&amp;wmode=transparent" referrerpolicy="strict-origin-when-cross-origin" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
 	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
@@ -818,8 +826,16 @@ func TestReplaceYoutubeURL(t *testing.T) {
 }
 
 func TestReplaceSecureYoutubeURL(t *testing.T) {
+	os.Clearenv()
+
+	var err error
+	config.Opts, err = config.NewConfigParser().ParseEnvironmentVariables()
+	if err != nil {
+		t.Fatalf(`Parsing failure: %v`, err)
+	}
+
 	input := `<iframe src="https://www.youtube.com/embed/test123"></iframe>`
-	expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
+	expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123" referrerpolicy="strict-origin-when-cross-origin" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
 	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
@@ -828,8 +844,16 @@ func TestReplaceSecureYoutubeURL(t *testing.T) {
 }
 
 func TestReplaceSecureYoutubeURLWithParameters(t *testing.T) {
+	os.Clearenv()
+
+	var err error
+	config.Opts, err = config.NewConfigParser().ParseEnvironmentVariables()
+	if err != nil {
+		t.Fatalf(`Parsing failure: %v`, err)
+	}
+
 	input := `<iframe src="https://www.youtube.com/embed/test123?rel=0&amp;controls=0"></iframe>`
-	expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123?rel=0&amp;controls=0" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
+	expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123?rel=0&amp;controls=0" referrerpolicy="strict-origin-when-cross-origin" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
 	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
@@ -838,8 +862,16 @@ func TestReplaceSecureYoutubeURLWithParameters(t *testing.T) {
 }
 
 func TestReplaceYoutubeURLAlreadyReplaced(t *testing.T) {
+	os.Clearenv()
+
+	var err error
+	config.Opts, err = config.NewConfigParser().ParseEnvironmentVariables()
+	if err != nil {
+		t.Fatalf(`Parsing failure: %v`, err)
+	}
+
 	input := `<iframe src="https://www.youtube-nocookie.com/embed/test123?rel=0&amp;controls=0" sandbox="allow-scripts allow-same-origin"></iframe>`
-	expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123?rel=0&amp;controls=0" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
+	expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123?rel=0&amp;controls=0" referrerpolicy="strict-origin-when-cross-origin" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
 	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
@@ -848,8 +880,16 @@ func TestReplaceYoutubeURLAlreadyReplaced(t *testing.T) {
 }
 
 func TestReplaceProtocolRelativeYoutubeURL(t *testing.T) {
+	os.Clearenv()
+
+	var err error
+	config.Opts, err = config.NewConfigParser().ParseEnvironmentVariables()
+	if err != nil {
+		t.Fatalf(`Parsing failure: %v`, err)
+	}
+
 	input := `<iframe src="//www.youtube.com/embed/Bf2W84jrGqs" width="560" height="314" allowfullscreen="allowfullscreen"></iframe>`
-	expected := `<iframe src="https://www.youtube-nocookie.com/embed/Bf2W84jrGqs" width="560" height="314" allowfullscreen="allowfullscreen" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
+	expected := `<iframe src="https://www.youtube-nocookie.com/embed/Bf2W84jrGqs" width="560" height="314" allowfullscreen="allowfullscreen" referrerpolicy="strict-origin-when-cross-origin" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
 	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
@@ -868,7 +908,7 @@ func TestReplaceYoutubeURLWithCustomURL(t *testing.T) {
 	}
 
 	input := `<iframe src="https://www.youtube.com/embed/test123?version=3&#038;rel=1&#038;fs=1&#038;autohide=2&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent"></iframe>`
-	expected := `<iframe src="https://invidious.custom/embed/test123?version=3&amp;rel=1&amp;fs=1&amp;autohide=2&amp;showsearch=0&amp;showinfo=1&amp;iv_load_policy=1&amp;wmode=transparent" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
+	expected := `<iframe src="https://invidious.custom/embed/test123?version=3&amp;rel=1&amp;fs=1&amp;autohide=2&amp;showsearch=0&amp;showinfo=1&amp;iv_load_policy=1&amp;wmode=transparent" referrerpolicy="strict-origin-when-cross-origin" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
 	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {