Fix exponential DOM issue in unwrap - #10
Merged
Merged
Conversation
This fixes an issue in the current implementation where if `sanitize` is
called on an HTML with deep nested unallowed elements it creates an
exponential number of new elements and can eventually exhaust the
available memory.
For example, if you have this HTML:
<x><y><z>blabla</z></y></x>
The code first hits `<x>` and inserts its `.innerHTML` after it:
<x><y><z>blabla</z></y></x>
<y><z>blabla</z></y>
Then it hits the inner `<y>`, and same thing:
<x><y><z>blabla</z></y>
<z>blabla</z></x>
<y><z>blabla</z></y>
Then the inner `<z>`:
<x><y><z>blabla</z>
blabla</y>
<z>blabla</z></x>
<y><z>blabla</z></y>
Then the first `<z>`鈥檚 copy, etc.
At the end, there are 7 nodes in the document (2^3-1).
If you raise the depth from 3 to 20, you get 2^20-1=1M nodes.
Note that there is also a performance issue as `.innerHTML` serializes
the whole DOM and then `insertAdjacentHTML` unserializes it.
This commit fixes both the exponential issue and the
serialization/unserialization.
Owner
|
Thank you for the research. I'll release this in the next patch version. |
Owner
|
Available in version v1.0.8. Thank you again. |
12 tasks
bfontaine
added a commit
to bfontaine/chatwoot
that referenced
this pull request
Jul 9, 2026
This release includes a [patch][1] that fixes an [issue][2] affecting Chatwoot: in some cases, if you receive a malformed email with deeply-nested tags considered unvalid by `lettersanitizer`, just selecting the email in your inbox causes the browser tab or even the whole computer to freeze, due to RAM exhaustion. [1]: mat-sz/lettersanitizer#10 [2]: GHSA-hhw2-373g-hx77 Also, bump vue-letter from 0.2.1 to 0.2.2, which bumped its own lettersanitizer dependency to 1.0.8.
bfontaine
added a commit
to bfontaine/chatwoot
that referenced
this pull request
Jul 9, 2026
This release includes a [patch][1] that fixes an [issue][2] affecting Chatwoot: in some cases, if you receive a malformed email with deeply-nested tags considered unvalid by `lettersanitizer`, just selecting the email in your inbox causes the browser tab or even the whole computer to freeze, due to RAM exhaustion. [1]: mat-sz/lettersanitizer#10 [2]: GHSA-hhw2-373g-hx77 Also, bump vue-letter from 0.2.1 to 0.2.2, which bumped its own lettersanitizer dependency to 1.0.8.
bfontaine
added a commit
to bfontaine/chatwoot
that referenced
this pull request
Jul 9, 2026
This release includes a [patch][1] that fixes an [issue][2] affecting Chatwoot: in some cases, if you receive a malformed email with deeply-nested tags considered unvalid by `lettersanitizer`, just selecting the email in your inbox causes the browser tab or even the whole computer to freeze, due to RAM exhaustion. [1]: mat-sz/lettersanitizer#10 [2]: GHSA-hhw2-373g-hx77 Also, bump vue-letter from 0.2.1 to 0.2.2, which bumped its own lettersanitizer dependency to 1.0.8.
bfontaine
added a commit
to bfontaine/chatwoot
that referenced
this pull request
Jul 9, 2026
This release includes a [patch][1] that fixes an [issue][2] affecting Chatwoot: in some cases, if you receive a malformed email with deeply-nested tags considered unvalid by `lettersanitizer`, just selecting the email in your inbox causes the browser tab or even the whole computer to freeze, due to RAM exhaustion. [1]: mat-sz/lettersanitizer#10 [2]: GHSA-hhw2-373g-hx77 Also, bump vue-letter from 0.2.1 to 0.2.2, which bumped its own lettersanitizer dependency to 1.0.8.
bfontaine
added a commit
to bfontaine/chatwoot
that referenced
this pull request
Jul 13, 2026
This release includes a [patch][1] that fixes an [issue][2] affecting Chatwoot: in some cases, if you receive a malformed email with deeply-nested tags considered unvalid by `lettersanitizer`, just selecting the email in your inbox causes the browser tab or even the whole computer to freeze, due to RAM exhaustion. [1]: mat-sz/lettersanitizer#10 [2]: GHSA-hhw2-373g-hx77 Also, bump vue-letter from 0.2.1 to 0.2.2, which bumped its own lettersanitizer dependency to 1.0.8.
bfontaine
added a commit
to bfontaine/chatwoot
that referenced
this pull request
Jul 14, 2026
This release includes a [patch][1] that fixes an [issue][2] affecting Chatwoot: in some cases, if you receive a malformed email with deeply-nested tags considered unvalid by `lettersanitizer`, just selecting the email in your inbox causes the browser tab or even the whole computer to freeze, due to RAM exhaustion. [1]: mat-sz/lettersanitizer#10 [2]: GHSA-hhw2-373g-hx77 Also, bump vue-letter from 0.2.1 to 0.2.2, which bumped its own lettersanitizer dependency to 1.0.8.
bfontaine
added a commit
to bfontaine/chatwoot
that referenced
this pull request
Jul 16, 2026
This release includes a [patch][1] that fixes an [issue][2] affecting Chatwoot: in some cases, if you receive a malformed email with deeply-nested tags considered unvalid by `lettersanitizer`, just selecting the email in your inbox causes the browser tab or even the whole computer to freeze, due to RAM exhaustion. [1]: mat-sz/lettersanitizer#10 [2]: GHSA-hhw2-373g-hx77 Also, bump vue-letter from 0.2.1 to 0.2.2, which bumped its own lettersanitizer dependency to 1.0.8.
sojan-official
pushed a commit
to chatwoot/chatwoot
that referenced
this pull request
Aug 12, 2026
# Pull Request Template ## Description This PR bumps lettersanitizer to 1.0.8, because that release includes a [patch][1] that fixes an [issue][2] affecting Chatwoot: in some cases, if you receive a malformed email with deeply-nested tags considered unvalid by `lettersanitizer`, just selecting the email in your inbox causes the browser tab or even the whole computer to freeze, due to RAM exhaustion. [1]: mat-sz/lettersanitizer#10 [2]: GHSA-hhw2-373g-hx77 Edit: also bump `vue-letter` to 0.2.2 to update its own `lettersanitizer` dependency (mat-sz/vue-letter#3), per #14959 (comment). ## Type of change Please delete options that are not relevant. - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality not to work as expected) - [ ] This change requires a documentation update ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] ~~I have commented on my code, particularly in hard-to-understand areas~~ - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules
gabrieljablonski
pushed a commit
to fazer-ai/chatwoot
that referenced
this pull request
Aug 30, 2026
# Pull Request Template ## Description This PR bumps lettersanitizer to 1.0.8, because that release includes a [patch][1] that fixes an [issue][2] affecting Chatwoot: in some cases, if you receive a malformed email with deeply-nested tags considered unvalid by `lettersanitizer`, just selecting the email in your inbox causes the browser tab or even the whole computer to freeze, due to RAM exhaustion. [1]: mat-sz/lettersanitizer#10 [2]: GHSA-hhw2-373g-hx77 Edit: also bump `vue-letter` to 0.2.2 to update its own `lettersanitizer` dependency (mat-sz/vue-letter#3), per chatwoot#14959 (comment). ## Type of change Please delete options that are not relevant. - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality not to work as expected) - [ ] This change requires a documentation update ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] ~~I have commented on my code, particularly in hard-to-understand areas~~ - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi Mat,
This is the PR for the fix. I copy the explanation below (also in the commit message) for other readers, but it鈥檚 the same explanation that I sent you via email.
I didn鈥檛 include unit tests as you said you would write them; tell me if you want some.
This fixes an issue in the current implementation where if
sanitizeis called on an HTML with deep nested unallowed elements it creates an exponential number of new elements and can eventually exhaust the available memory.For example, if you have this HTML:
The code first hits
<x>and inserts its.innerHTMLafter it:Then it hits the inner
<y>, and same thing:Then the inner
<z>:Then the first
<z>鈥檚 copy, etc.At the end, there are 7 nodes in the document (2^3-1). If you raise the depth from 3 to 20, you get 2^20-1=1M nodes.
Note that there is also a performance issue as
.innerHTMLserializes the whole DOM and theninsertAdjacentHTMLunserializes it.This PR fixes both the exponential issue and the serialization/unserialization.