Skip to content

Support JSDOM (with DOMPurify) #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jonasheschl opened this issue Mar 31, 2025 · 7 comments
Open

Support JSDOM (with DOMPurify) #2

jonasheschl opened this issue Mar 31, 2025 · 7 comments

Comments

@jonasheschl
Copy link

jonasheschl commented Mar 31, 2025

Currently the DOMPurify pipe will always run its purification using the browser. It would be useful to have an option in the DOMPurify pipe to use JSDom instead.

In addition, while there is a pipe for parse5, there is no pipe for JSDom. Even though JSDom uses parse5, it can sometimes exhibit parsing differentials to parse5 itself.

The pipe for JSDom could look something like this, where HTML_STRING is the HTML to be parsed.

import { JSDOM } from "jsdom";

const window = new JSDOM(HTML_STRING).window;

console.log(window.document.documentElement.innerHTML)
@B-i-t-K
Copy link
Member

B-i-t-K commented Mar 31, 2025

Sadly there is limitations, jsdom was not made to work in the browser. I had a bunch of error while trying to add it and this is why I choose to add parse5 instead.

If you manage to make it work, submit a pull request and I will happily merge it.

@jonasheschl
Copy link
Author

jonasheschl commented Mar 31, 2025

I am working on adding it right now. I'll probably do so using an API route. JSDom theoretically officially works on the browser with browserify, but I don't trust browserify to not introduce behaviour changes.

@jonasheschl
Copy link
Author

jonasheschl commented Mar 31, 2025

Got it working locally by running JSDom on the server with a Nuxt API route. Two issues though:

  1. Dynamically loading JSDom versions serverside does not work (with jsdelivr). Jsdelivr does not serve JSDom since JSDom requires node. Currently I have just installed the JSDom package regularly. While it would be possible to install all available JSDom versions with separate names and use those, this would bloat the server bundle massively and require a patch each time a new JSDom version is released. It is probably possible to download and import JSDom versions from npm dynamically at runtime on the serverside, but that would probably be quite some work to get running properly.
  2. Much worse though is that JSDom does not guarantee a safe sandbox. Meaning that an attacker could use the JSDom API call to get RCE on the Dom-Explorer server. Since JSDom sees a safe sandbox as out of scope, there really is no way to fix this without running JSDom in containers or similar, which would be overkill.

So the only realistic approach I see -- especially because of 2. -- is to hide the JSDom parser behind a featureflag. Maybe display JSDom in the frontend always, but greyed out with a note that JSDom is only available when hosting Dom-Explorer yourself. I suppose that the kind of people looking into JSDom parsing differentials are fine with self-hosting Dom-Explorer.

Image

@B-i-t-K let me know what your thoughts on that are. If you are fine with these trade-offs I'll look into cleaning up my code and opening up a PR. I would also look into adding a setting for the DOMPurify pipe to run it with JSDom serverside.

@jonasheschl
Copy link
Author

I have pushed my current patches to https://github.com/jonasheschl/Dom-Explorer-JSDom

@jonasheschl
Copy link
Author

Thoughts @B-i-t-K ?

@B-i-t-K
Copy link
Member

B-i-t-K commented May 6, 2025

Sorry for the delay, I like the way you added JsDom, but I want to be able to publish dom-explorer as a github page which remove the possibility for backend pipe like this one.

I don't know yet if I want to add a compilation flag or maybe two different branches for people who are self hosting.

@jonasheschl
Copy link
Author

I can fully understand that. I have some research coming up where I might continue to develop my fork. If you want to merge it (or parts of it) into the mainline lmk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants