CVE-2021-41086 (JavaScript, published 2021-09-21T21:15Z)
Description: value: jsuites is an open source collection of common required javascript web components. In affected versions users are subject to cross site scripting (XSS) attacks via clipboard content. jsuites is vulnerable to DOM based XSS if the user can be tricked into copying _anything_ from a malicious and pasting it into the html editor. This is because a part of the clipboard content is directly written to `innerHTML` allowing for javascript injection and thus XSS. Users are advised to update to version 4.9.11 to resolve.
Severity: LOW (CVSS v3 base score: 5.4)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/jsuites/jsuites
Files changed:
dist/jsuites.basic.css
dist/jsuites.basic.js
dist/jsuites.css
dist/jsuites.js
package.json
src/contextmenu.css
src/editor.js
src/toolbar.js
Commit message: Editor sec fix, toolbar reponsiveness tracking fix, responsive
contextmenu. v4.9.10

Vulnerable code:
    var version = '4.9.9';
    var remove = [HTMLUnknownElement];
           if (element.tagName == 'IMG') {
                   element.remove();
        span.innerHTML = data;
        parse(span);
    var obj = {};
            // Width of the c
            var rect = el.parentNode.getBoundingClientRect();
            var available = rect.width;
    var version = '4.9.9';
    var remove = [HTMLUnknownElement];
           if (element.tagName == 'IMG') {
                   element.remove();
        span.innerHTML = data;
        parse(span);
    var obj = {};
            // Width of the c
            var rect = el.parentNode.getBoundingClientRect();
            var available = rect.width;
    "version": "4.9.9",
    var remove = [HTMLUnknownElement];
           if (element.tagName == 'IMG') {
                   element.remove();
        span.innerHTML = data;
        parse(span);
    var obj = {};
            // Width of the c
            var rect = el.parentNode.getBoundingClientRect();
            var available = rect.width;

Fixed code:
@media only screen and (max-width: 420px) {
    .jcontextmenu {
        top: initial !important;
        left: 0px !important;
        bottom: 0px !important;
        width: 100vw;
        height: 260px;
        overflow: scroll;
        animation: slide-bottom-in 0.4s forwards;
    }
    .jcontextmenu div {
        width: 100%;
        text-align: center;
        border-bottom: 1px solid #ccc;
        padding: 15px;
    }
    .jcontextmenu > div::before {
        display: none;
    }
    .jcontextmenu a {
        font-size: 1.4em;
        text-transform: uppercase;
    }
    .jcontextmenu span {
        display: none;
    }
    .jcontextmenu span {
        display: none;
    }
    .jcontextmenu hr {
        display: none;
    }
}

    var version = '4.4.0';
    var remove = [HTMLUnknownElement,HTMLAudioElement,HTMLEmbedElement,HTMLIFrameElement,HTMLTextAreaElement,HTMLInputElement,HTMLScriptElement];
           if (element.tagName.toUpperCase() == 'IMG') {
                   element.parentNode.removeChild(element);
        var parser = new DOMParser();
        var d = parser.parseFromString(data, "text/html");
        parse(d);
        span.innerHTML = d.firstChild.innerHTML;
    // New instance
    var obj = { type:'toolbar' };
        maxWidth: null,
            // Width of the c
            var rect = el.parentNode.getBoundingClientRect();
            if (! obj.options.maxWidth) {
                obj.options.maxWidth = rect.width;
            }
            // Max width
            var width = parseInt(obj.options.maxWidth); 
            var available = obj.options.maxWidth;
@media only screen and (max-width: 420px) {
    .jcontextmenu {
        top: initial !important;
        left: 0px !important;
        bottom: 0px !important;
        width: 100vw;
        height: 260px;
        overflow: scroll;
        animation: slide-bottom-in 0.4s forwards;
    }
    .jcontextmenu div {
        width: 100%;
        text-align: center;
        border-bottom: 1px solid #ccc;
        padding: 15px;
    }
    .jcontextmenu > div::before {
        display: none;
    }
    .jcontextmenu a {
        font-size: 1.4em;
        text-transform: uppercase;
    }
    .jcontextmenu span {
        display: none;
    }
    .jcontextmenu span {
        display: none;
    }
    .jcontextmenu hr {
        display: none;
    }
}

    var version = '4.4.0';
    var remove = [HTMLUnknownElement,HTMLAudioElement,HTMLEmbedElement,HTMLIFrameElement,HTMLTextAreaElement,HTMLInputElement,HTMLScriptElement];
           if (element.tagName.toUpperCase() == 'IMG') {
                   element.parentNode.removeChild(element);
        var parser = new DOMParser();
        var d = parser.parseFromString(data, "text/html");
        parse(d);
        span.innerHTML = d.firstChild.innerHTML;
    // New instance
    var obj = { type:'toolbar' };
        maxWidth: null,
            // Width of the c
            var rect = el.parentNode.getBoundingClientRect();
            if (! obj.options.maxWidth) {
                obj.options.maxWidth = rect.width;
            }
            // Max width
            var width = parseInt(obj.options.maxWidth); 
            var available = obj.options.maxWidth;
    "version": "4.9.10",
}

@media only screen and (max-width: 420px) {
    .jcontextmenu {
        top: initial !important;
        left: 0px !important;
        bottom: 0px !important;
        width: 100vw;
        height: 260px;
        overflow: scroll;
        animation: slide-bottom-in 0.4s forwards;
    }
    .jcontextmenu div {
        width: 100%;
        text-align: center;
        border-bottom: 1px solid #ccc;
        padding: 15px;
    }
    .jcontextmenu > div::before {
        display: none;
    }
    .jcontextmenu a {
        font-size: 1.4em;
        text-transform: uppercase;
    }
    .jcontextmenu span {
        display: none;
    }
    .jcontextmenu span {
        display: none;
    }
    .jcontextmenu hr {
        display: none;
    }
    var remove = [HTMLUnknownElement,HTMLAudioElement,HTMLEmbedElement,HTMLIFrameElement,HTMLTextAreaElement,HTMLInputElement,HTMLScriptElement];
           if (element.tagName.toUpperCase() == 'IMG') {
                   element.parentNode.removeChild(element);
        var parser = new DOMParser();
        var d = parser.parseFromString(data, "text/html");
        parse(d);
        span.innerHTML = d.firstChild.innerHTML;
    // New instance
    var obj = { type:'toolbar' };
        maxWidth: null,
            // Width of the c
            var rect = el.parentNode.getBoundingClientRect();
            if (! obj.options.maxWidth) {
                obj.options.maxWidth = rect.width;
            }
            // Max width
            var width = parseInt(obj.options.maxWidth); 
            var available = obj.options.maxWidth;