cure53 / DOMPurify

DOMPurify - a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. DOMPurify works with a secure default, but offers a lot of configurability and hooks. Demo:
https://cure53.de/purify
Other
13.34k stars 690 forks source link

DOMPurify and Trusted Types - Clarification to Docs #939

Closed cancan101 closed 3 months ago

cancan101 commented 3 months ago

This issue proposes an improvement to the README which clarifies how to use DOMPurify.sanitize along with trustedTypes.createPolicy, specifically when using Typescript.

Background & Context

I am trying to create a trustedTypes policy and to use DOMPurify.sanitize in the createHTML. I am trying to do this in Typescript without resorting to any.

I have read the docs here: https://github.com/cure53/DOMPurify?tab=readme-ov-file#what-about-dompurify-and-trusted-types and looked at other usage in GitHub and and am confused.

Bug

This does not work (ie TS won't compile due to type issues):

window.trustedTypes!.createPolicy('default', {
  createHTML: (to_escape) =>
    DOMPurify.sanitize(to_escape, { RETURN_TRUSTED_TYPE: true }),
});

whereas both of these work:

window.trustedTypes!.createPolicy('default', {
  createHTML: (to_escape) =>
    DOMPurify.sanitize(to_escape, { RETURN_TRUSTED_TYPE: false }),
});

and

window.trustedTypes!.createPolicy('default', {
  createHTML: (to_escape) =>
    DOMPurify.sanitize(to_escape, { RETURN_TRUSTED_TYPE: true }).toString(),
});

Should I just use one of those two options or is there a way to get this to work with RETURN_TRUSTED_TYPE: true without having to resort to toString or any?

Feature

I suggest providing an more complete example in the docs of the correct usage.

cure53 commented 3 months ago

Hmmmm, so the idea is that the policy method returns a string, correct?

cancan101 commented 3 months ago

Returning a string loses some type information, namely that the string contains a sanitized string. Is there any option within trustedTypes to allow the policy to accept a function that returns TrustedHTML?

cure53 commented 3 months ago

I am not sure what you mean, could you clarify a bit more what you want to achieve, what does not work and whether this is a DOMPurify issue or a general TrustedType question?

What do you mean with "This does not work"?

tosmolka commented 3 months ago

I think CreateHTMLCallback from Trusted Types spec by design expects DOMString return type, not TrustedHTML interface. So I don't think your first example is a bug, I think it works as expected.

+1 on providing more complete example in the docs of the correct usage, this could certainly help others who are new to using DOMPurify with Trusted Types

cure53 commented 3 months ago

Ooooh, okay, now this makes sense, thank you @tosmolka :slightly_smiling_face:

About the README, happy to update, please define "more complete", what needs to be added? I am unsure what to best recommend - since I want to refrain from recommending strings after all.

cure53 commented 3 months ago

@cancan101 Please let us know what you have in mind with a more comprehensive example, happy to update the README once we know (also feel free to send over a PR if that is easier).

cancan101 commented 3 months ago

Perhaps something along the line of:

// to create a Policy in trustedTypes using DOMPurify
// RETURN_TRUSTED_TYPE: false is needed as createHTML expects a normal string rather than TrustedHTML
window.trustedTypes!.createPolicy('default', {
  createHTML: (to_escape) =>
    DOMPurify.sanitize(to_escape, { RETURN_TRUSTED_TYPE: false }),
});
cure53 commented 3 months ago

That works for me, thanks :smile:

cure53 commented 3 months ago

We have updated the README, that should do the trick me believes?