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
14.12k stars 733 forks source link

Issue regarding sanitization behavior #1007

Closed DeepakGoyalDev closed 1 month ago

DeepakGoyalDev commented 1 month ago

Issue Proposal: [Bug/Feature]

Background & Context

I am working with HTML email templates submitted by users, and I want to ensure that these templates remain unchanged unless a security issue is detected. Currently, I am using DOMPurify for sanitization. However, I have encountered a problem where DOMPurify removes a significant amount of code—specifically, DOMPurify.removed indicates that 550 entries have been removed.

Removed Elements:

Additionally, comments are also being removed.

Example:

For one specific email, I need to maintain certain configurations that are no longer possible due to these removals. I am uncertain about what users might paste, so I require a robust solution.


const sanitizedHtml = DOMPurify.sanitize(html, {
    FORBID_TAGS: ["script"],
    // FORBID_ATTR: ['onerror', 'onclick', 'onload', 'onsubmit', 'onmouseover'], // Add more event attributes as needed
    WHOLE_DOCUMENT: true, // Treats input as a full document
    KEEP_CONTENT: true, // Ensures the content within the head is retained
    SANITIZE_DOM: false,
    FORBID_ATTR: [],
    FORCE_BODY: true,
    SANITIZE_NAMED_PROPS: false,
    ADD_TAGS: ['link', 'meta', 'head', 'body', 'html', 'title', 'style', 'comment'], // Include essential tags like title and style (if needed)
    ADD_ATTR: ["style", "mktoname", "mktomodulescope", "units", "mktolockimgstyle", "target", "content", "http-equiv", "date-duplicable"]
});

### Request for Suggestions
I have been experimenting with various configurations but have yet to find a successful solution. Please advise on any configurations or methods that could help me retain the integrity of user-submitted HTML while ensuring security.
DeepakGoyalDev commented 1 month ago

It resolves the issue, But sure can I use it in production code...

    DOMPurify.addHook('uponSanitizeAttribute', (node, data) => {
      if (!data.attrName.match(/^on\w+/)) {
        data.forceKeepAttr = true;
      }
    });

    const sanitized HTML = DOMPurify.sanitize(html, {
      FORBID_TAGS: ["script"],
      WHOLE_DOCUMENT: true, // Treats input as a full document
      KEEP_CONTENT: true, // Ensures the content within the head is kept
      ...(isLayoutParserV2Enabled && {
        ADD_TAGS: ['link', 'head', 'meta', 'body', 'html', 'title', 'style'],
        SANITIZE_DOM: false,
      })
    })

    DOMPurify.removeAllHooks();
DeepakGoyalDev commented 1 month ago

Hi @cure53, Can you please confirm if is it okay to use it in the production code?

If not, Can you suggest How to track this situation?

 DOMPurify.addHook('uponSanitizeAttribute', (node, data) => {
      if (!data.attrName.match(/^on\w+/)) {
        data.forceKeepAttr = true;
      }
    });

    const sanitized HTML = DOMPurify.sanitize(html, {
      FORBID_TAGS: ["script"],
      WHOLE_DOCUMENT: true, // Treats input as a full document
      KEEP_CONTENT: true, // Ensures the content within the head is kept
      ...(isLayoutParserV2Enabled && {
        ADD_TAGS: ['link', 'head', 'meta', 'body', 'html', 'title', 'style'],
        SANITIZE_DOM: false,
      })
    })

    DOMPurify.removeAllHooks();
cure53 commented 1 month ago

Hey there, I cannot make a judgement call here as I do not know your application.