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.67k stars 698 forks source link

Question regarding USE_PROFILES config option #879

Closed george-thomas-hill closed 9 months ago

george-thomas-hill commented 9 months ago

The documentation gives several examples of how to use the USE_PROFILES configuration option.

However, it does not explicitly define that option or say exactly what it does.

Nor does it spell out the range of possible values to supply.

Could you please add a bit to the documentation to address that?

Thank you.

cure53 commented 9 months ago

Heya, sure - happy to look into that. How would you improve it?

This is what we have:

// allow all safe HTML elements but neither SVG nor MathML
// note that the USE_PROFILES setting will override the ALLOWED_TAGS setting
// so don't use them together
const clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {html: true}});

// allow all safe SVG elements and SVG Filters, no HTML or MathML
const clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {svg: true, svgFilters: true}});

// allow all safe MathML elements and SVG, but no SVG Filters
const clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {mathMl: true, svg: true}});
george-thomas-hill commented 9 months ago

I think my first question is the following:

Is . . .

const clean = DOMPurify.sanitize(dirty);

. . . equivalent to . . .

const clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {}});

. . . or to . . .

const clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {html: false, mathMl: false, svg: false, svgFilters: false}});

. . . or to . . .

const clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {html: true, mathMl: true, svg: true, svgFilters: true}});

. . . or to something else?

My second question is:

Are there any other key-value combinations that can be provided in the object used as the value of USE_PROFILES?

My third question is:

If I use . . .

const clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {hmtl: true}});

. . . and dirty contains malicious mathMl code, am I protected, or am I unprotected?

Thank you!

george-thomas-hill commented 9 months ago

My fourth question—and I guess it's the key question—is:

If I use . . .

const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true, mathMl: false, } });

. . . does it let through all MathML tags or does it let through no MathML tags?

cure53 commented 9 months ago

I think the answer is very simple :)

// only HTML, nothing else is allowed, all SVG and MathML elements get removed
DOMPurify.sanitize('<html>yay</html><svg>nay</svg><math>nay</math>', {USE_PROFILES: {html: true}}); 
// only SVG, nothing else is allowed, all HTML and MathML elements get removed
DOMPurify.sanitize('<html>nay</html><svg>yay</svg><math>nay</math>', {USE_PROFILES: {svg: true}}); 

The idea is, that by using profiles, you can select what you want more easily and navigate around complex allow-lists.

USE_PROFILES: {html: true} // HTML only
USE_PROFILES: {svg: true} // SVG only but no crazy filters
USE_PROFILES: {svg: true, svgFilters: true} // SVG only and yes, all the crazy filters
USE_PROFILES: {mathMl: true} // MathML only
USE_PROFILES: {mathMl: true, html: true} // HTML and MathML only, no SVG

In practical terms, most folks will likely use the {html: true} option and be happy for 99% of all use cases.

george-thomas-hill commented 9 months ago

OK. I get it. Thank you.