Skip to content

The literal-content gate ignores the renderer's foreign-content escaping and custom receivers #474

Description

@jmanico

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{}&lt;b&gt;x&lt;/b&gt;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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    releasedIssue has been released

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions