🛡️ CVE-2026-62324 — jodit

🟡 CVSS 5.4 — Medium ✅ No Known Exploit CWE-79 NVD
5.4
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Jodit has incomplete javascript: scheme normalization in sanitizeHTMLElement href check that allows link XSS ### Summary jodit's `sanitizeHTMLElement` neutralizes a `javascript:` `href` using a bare `href.trim().indexOf('javascript') === 0` check. This omits the normalization jodit applies to every other URL attribute: `isDangerousUrl` strips control bytes with `value.replace(/[\u0000-\u0020]+/g, '')` and lowercases the value before testing the scheme. Because the `href` check does neither, it is bypassed by three obfuscation classes, all confirmed firing on click against the shipped 4.12.30 build: 1. Case variants: `JAVASCRIPT:`, `Javascript:`, `jaVaScRiPt:` (the check is case-sensitive). 2. A leading C0 control byte, e.g. a `\x01` prefix before lowercase `javascript:` (`trim()` does not remove bytes in the `\x00`-`\x08` / `\x0e`-`\x1f` range, but the browser strips a leading control byte before resolving the scheme). 3. An embedded tab or newline inside the scheme, e.g. `java\tscript:` or `java\nscript:` (the browser strips tab/newline from a URL, but `indexOf('javascript')` sees the broken word and does not match). The dangerous href survives `editor.value =` assignment and the on-change LazyWalker, persisting in the stored editor value. A victim who clicks the link in any consumer that renders the stored value (readonly editor, server-rendered page, `innerHTML` consumer) runs attacker-controlled JS in that page's origin. ### Details The check is in `sanitizeHTMLElement` at `src/core/helpers/html/safe-html.ts:213`: ```js if (safeJavaScriptLink && href && href.trim().indexOf('javascript') === 0) { attr(elm, 'href', location.protocol + '//' + href); effected = true; } ``` `href.trim()` removes leading/trailing ASCII whitespace only, and `indexOf('javascript')` is case-sensitive and literal. So the check fails to fire whenever the scheme is upper/mixed-case, prefixed by a non-whitespace control byte, or split by an embedded tab/newline - all of which a browser still resolves to `javascript:` on click (URI schemes are case-insensitive per RFC 3986 section 3.1; leading control bytes, tabs and newlines are stripped from a URL during parsing). The same file already contains the correct routine, `isDangerousUrl()` (line 176), used for every other URL attribute (`src`, `data`, `action`, `formaction`, `poster`, `background`, `xlink:href`): ```js function isDangerousUrl(value, tagName) { const normalized = value.replace(/[\u0000-\u0020]+/g, '').toLowerCase(); if (/^(?:javascript|vbscript|livescript|mocha):/.test(normalized)) { return true; } // ... } ``` `isDangerousUrl` strips every control byte and ASCII space (`/[\u0000-\u0020]+/g`) and lowercases before testing the scheme, so it resists all three obfuscations. But `href` never goes through it: the attribute list `isDangerousUrl` is applied to (`URL_ATTRIBUTES`) is commented "besides href", and `href` is handled only by the weaker `indexOf` check. Both the synchronous value-set path (`onBeforeSetNativeEditorValue` -> `safeHTML` -> `sanitizeHTMLElement`) and the asynchronous on-change path (`sanitizeAttributes` -> `sanitizeHTMLElement`) use that same weak check. Positive controls (filter is otherwise live): a plain lowercase `javascript:` href IS neutralized: jodit rewrites the value to `location.protocol + '//' + href`, so it reads `about://javascript:...` on an about:blank test page and `https://javascript:...` on an https page. A leading ASCII space or tab IS caught by `trim()`; the bypass is specific to the un-normalized forms above. ### Proof of concept Default configuration. Assign a payload to the editor and read back the stored value: ```js const editor = Jodit.make('#editor'); editor.value = 'click me'; // editor.value getter returns the href unchanged: //

click me

document.getElementById('view').innerHTML = editor.value; // Clicking "click me" runs alert(document.domain) in the consumer's origin. ``` The same persists for the leading-control-byte form (a `\x01` prefix before lowercase `javascript:`) and the embedded-tab/newline forms (`java\tscript:` / `java\nscript:`). Verified live on the shipped `es2021/jodit.min.js` for jodit 4.12.30. Positive controls in the same run: `` stripped; lowercase `javascript:` neutralized to `location.protocol + '//' + href` (`about://...` on the about:blank test page used here, `https://...` on an https page). ### Impact Stored click-XSS. An attacker with write access to an editor instance (content author, or comment author in a multi-user application) stores a crafted `javascript:` link. Any user who clicks it in a view that renders the stored value (readonly editor, server-rendered page, `innerHTML` consumer) runs attacker-controlled JS in that origin. One user interaction (the click) is required. A consumer that re-sanitizes the editor output

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs low-level privileges on the target. A user must be tricked into taking some action. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality low, integrity low, availability none.

Weakness class

CVE-2026-62324 is classified as CWE-79: Cross-site Scripting (XSS). User-supplied data is written into a page without escaping, so attacker script runs in the browser of anyone who views it.

Affected software

CVE-2026-62324 is recorded against 2 packages.

  • jodit
  • unknown

Timeline and source

Published on 31 July 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.

References

github.com (Web)
github.com (Web)
github.com (Package)
github.com (Web)

Details

Severity Medium
CVSS Score 5.4
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
CWE CWE-79
Public Exploit ✅ No
Source NVD
Published 2026-07-31
Updated 2026-08-12
Modified 2026-07-31
Fix URL N/A

Affected Packages

Software From version Fixed in
jodit
unknown

Similar Threats

Vulnerability Monitoring

Track new vulnerabilities in jodit

CVE-2026-62324 is rated CVSS 5.4 Medium. BotEraser monitors your WordPress installation and notifies you when software you use appears in our vulnerability database.

Set Up Free Alerts →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.