Browse Source

fix(sanitizer): strip inner elements of blocked iframes

Previously, when an iframe was blocked by the allowlist check, its child
elements were still rendered as content. Now blocked iframes discard
their children, matching the behavior of allowed iframes.
Frédéric Guillot 1 week ago
parent
commit
293209098a

+ 4 - 0
internal/reader/sanitizer/sanitizer.go

@@ -291,6 +291,10 @@ func filterAndRenderHTML(buf *strings.Builder, n *html.Node, parsedBaseUrl *url.
 
 		htmlAttributes, hasAllRequiredAttributes := sanitizeAttributes(parsedBaseUrl, tag, n.Attr, sanitizerOptions)
 		if !hasAllRequiredAttributes {
+			if tag == "iframe" {
+				// A blocked iframe should not have its inner content rendered.
+				return nil
+			}
 			// The tag doesn't have every required attributes but we're still interested in its content
 			return filterAndRenderHTMLChildren(buf, n, parsedBaseUrl, sanitizerOptions, depth-1)
 		}

+ 12 - 0
internal/reader/sanitizer/sanitizer_test.go

@@ -397,6 +397,18 @@ func TestInvalidIFrame(t *testing.T) {
 	}
 }
 
+func TestBlockedIFrameWithChildElements(t *testing.T) {
+	config.Opts = config.NewConfigOptions()
+
+	input := `<iframe src="http://example.org/"><p>test</p></iframe>`
+	expected := ``
+	output := sanitizeHTMLWithDefaultOptions("http://example.com/", input)
+
+	if expected != output {
+		t.Errorf(`Wrong output: %q != %q`, expected, output)
+	}
+}
+
 func TestSameDomainIFrame(t *testing.T) {
 	config.Opts = config.NewConfigOptions()