GithubHelp home page GithubHelp logo

Comments (12)

cure53 avatar cure53 commented on July 24, 2024

Oh, that sounds bad, I'll have a look right away!

from dompurify.

cure53 avatar cure53 commented on July 24, 2024

I can reproduce the issue.

I think the problem here is the following: MSIE seems to recurse over this operation, because it appears to create a new textNode each time the text of the existing textNode is set.

That means, that upon setting the text, a new node appears that needs to be sanitized, then text is being set, creating a new textNode... and so on. Edge by the way has the same problem. I am looking into how to fix this now...

This example hangs:

DOMPurify.addHook('afterSanitizeElements', function(node) {
  if (node.nodeType && node.nodeType === document.TEXT_NODE) {
        node.textContent = 'foo';
  }
  return node;
});

This example does not:

DOMPurify.addHook('afterSanitizeElements', function(node) {
  if (node.nodeType && node.nodeType === document.TEXT_NODE) {
        node.innerText = 'foo';
  }
  return node;
});

from dompurify.

cure53 avatar cure53 commented on July 24, 2024

Okay, I came up with a first possible fix:

https://github.com/cure53/DOMPurify/compare/Experimental_Fix_for_89?expand=1

This fix stores a copy of the currently processed mode as oldNode, then compares the new incoming node (then currentNode) to the old node. If the new node and the old node are identical, the node iterator is told to step ahead one call and continue from there. This fixes the problem of IE and doesn't seem to affect other browsers. The tests are still running as expected.

This could be a security critical change so I'd kindly ask for review, @fhemberger and @neilj. I also think the fix is ugly but I cannot come up with something better right now.

from dompurify.

neilj avatar neilj commented on July 24, 2024

A few thoughts:

  1. I'm not convinced that the IE behaviour is wrong. The spec is slightly ambiguous, but I could certainly interpret it as saying you should replace the whole text node. The rules of the NodeIterator means the new node then comes after the cursor, so is returned next. As such, I don't see anything wrong that necessarily needs to change with the current code in DOMPurify: this should be fixed by the code using it (my recommendation is to simply replace textContent with data, since this then sets the data of the text node itself, which is what was originally intended). You could just as easily create an infinite loop by inserting a new element after the current element in a hook; this doesn't meant the library itself is broken.
  2. If you still do want to patch this particular case in the library, I don't think your fix will work (although I haven't actually checked, as I don't have IE handy). From the description above, the problem is that the text node is replaced. Therefore currentNode === oldNode would always be false, because they are different nodes, so you would still infinite loop. Also, the code formatting is completely inconsistent with the rest of the library:
if(currentNode === oldNode){
            nodeIterator.nextNode()
}

There should be a space after the if and before the {, and the next line is indented too much.

from dompurify.

cure53 avatar cure53 commented on July 24, 2024

@neilj The hang also happens with data and other properties/methods on Text. It seems only innerHTML and innerText are fine and I would not recommend using them here. IE appears to be "empirically" wrong as all other user agents don't cause a recursion and honestly, the code doesn't look like it should. Yet it still does because we use the node iterator internally. So it is at least partly our fault.

The fix surprisingly works, because in this situation, the result is indeed true. I didn't believe it myself at first but it is the case. So factually, the fix does tackle the problem, just not in a nice or logical way. But that's IE.

About the coding inconsistencies: True, you are 100% right. But at this stage of the fix (merely experimenting in an experimental branch) I don't care too much. Cosmetics when cosmetics are due. Now I want to find a working and reasonable fix.

from dompurify.

neilj avatar neilj commented on July 24, 2024

Fine. So actually IE is doing something very weird, not simply replacing the text node then. In that case, I have one small change I think. Instead of:

if (currentNode === oldNode) {
    nodeIterator.nextNode()
}

I think you want:

if (currentNode === oldNode) {
    continue;
}

We've already processed the old node, yes? So we don't want to process it again. The current code (if I understand the IE bug correctly now) skips the first node after the text node that's replaced, which is potentially a security hole.

from dompurify.

cure53 avatar cure53 commented on July 24, 2024

That makes much more sense, thanks! I'll add a test-case and then will post the diff here again for review.

from dompurify.

cure53 avatar cure53 commented on July 24, 2024

Okay, ready for review again:

https://github.com/cure53/DOMPurify/compare/Experimental_Fix_for_89?expand=1

from dompurify.

neilj avatar neilj commented on July 24, 2024

That looks good to me.

from dompurify.

cure53 avatar cure53 commented on July 24, 2024

Thanks, merging...

from dompurify.

cure53 avatar cure53 commented on July 24, 2024

@luhmann From what I can see we are good to close this issue. Any thoughts?

from dompurify.

luhmann avatar luhmann commented on July 24, 2024

Fix works perfectly for me. Thank you very much for the quick help.

from dompurify.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.