Follow-up from the review of #465.
isLiteralContentElement in ElementAndAttributePolicyBasedSanitizerPolicy re-derives the renderer's escaping decision from HtmlTextEscapingMode through HtmlStreamRenderer.safeName, but the renderer has a second input it does not: inside svg and math a style or script element's text is escaped as RCDATA, because browsers parse it as markup there. So a kept <style> inside <svg> now has its tags stripped by the policy where the renderer alone escaped and preserved them. With allowElements("svg","style","b").allowTextIn("style","svg"):
<svg><style>a{}<b>x</b>c{}</style></svg>
gave <svg><style>a{}<b>x</b>c{}</style></svg> before #465 and gives <svg><style>a{}c{}</style></svg> now. Safe either way, but lossy for no reason.
The related edge: through the safeName indirection the policy leaves xmp, listing and plaintext text unstripped because the shipped renderer renames them to pre and escapes; a custom HtmlStreamEventReceiver handed to PolicyFactory.apply does not rename, so it receives </noscript><img src=x onerror=alert(1)> as a text event verbatim. The renderer-side check added in #472 does not run for such a receiver either.
One shared predicate that both the policy and the renderer consult, taking the foreign-content depth into account, would keep the two from drifting.
Follow-up from the review of #465.
isLiteralContentElementinElementAndAttributePolicyBasedSanitizerPolicyre-derives the renderer's escaping decision fromHtmlTextEscapingModethroughHtmlStreamRenderer.safeName, but the renderer has a second input it does not: insidesvgandmathastyleorscriptelement's text is escaped as RCDATA, because browsers parse it as markup there. So a kept<style>inside<svg>now has its tags stripped by the policy where the renderer alone escaped and preserved them. WithallowElements("svg","style","b").allowTextIn("style","svg"):gave
<svg><style>a{}<b>x</b>c{}</style></svg>before #465 and gives<svg><style>a{}c{}</style></svg>now. Safe either way, but lossy for no reason.The related edge: through the
safeNameindirection the policy leavesxmp,listingandplaintexttext unstripped because the shipped renderer renames them topreand escapes; a customHtmlStreamEventReceiverhanded toPolicyFactory.applydoes not rename, so it receives</noscript><img src=x onerror=alert(1)>as a text event verbatim. The renderer-side check added in #472 does not run for such a receiver either.One shared predicate that both the policy and the renderer consult, taking the foreign-content depth into account, would keep the two from drifting.