VYPR
Critical severityNVD Advisory· Published Jul 25, 2022· Updated Aug 3, 2024

CVE-2022-35131

CVE-2022-35131

Description

Joplin v2.8.8 allows attackers to execute arbitrary commands via a crafted payload injected into the Node titles.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Joplin <= 2.8.8 allows XSS in the GotoAnything dialog via note titles, enabling remote code execution.

CVE-2022-35131 describes a cross-site scripting (XSS) vulnerability in Joplin version 2.8.8 and earlier, leading to remote code execution (RCE). The root cause is the use of dangerouslySetInnerHTML in the GotoAnything dialog component (GotoAnything.tsx), which renders user-provided note titles without proper HTML escaping [3][4]. The surroundKeywords function, designed to highlight search terms, failed to sanitize user input, allowing arbitrary JavaScript to be injected into the DOM [3].

An attacker can exploit this by creating a note with a JavaScript payload embedded in the title. When the victim uses the GotoAnything dialog (Ctrl+P) and searches for a term that matches the payload, the title is rendered as unescaped HTML [4]. The payload executes in the context of the Electron application, which has access to Node.js APIs. The attacker does not require authentication; sharing a notebook with a malicious note title is sufficient to trigger the vulnerability when the recipient searches notes [4].

Successful exploitation gives the attacker arbitrary code execution on the victim's system. Proof-of-concept payloads demonstrate launching calculator applications on both Windows and Linux, as well as establishing reverse shells [4]. The impact is severe because Joplin is used for note-taking and synchronization across multiple devices, and the vulnerability can spread via shared notebooks.

The issue was reported and fixed in June 2022 [4]. The commit e797ebb864fbf429a49b6d20e5779d0c9aa6c4d5 implements input escaping in the surroundKeywords function, mitigating the XSS [3]. Users should update to a patched version (2.9.0 or later). There is no evidence of exploitation in the wild, but the vulnerability is critical due to its high CVSS score and public proof-of-concept code.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
joplinnpm
< 2.9.12.9.1

Affected products

2

Patches

1
e797ebb864fb

Desktop: Security: Fixes XSS in GotoAnything dialog

https://github.com/laurent22/joplinLaurent CozicJun 30, 2022via ghsa
1 file changed · +14 3
  • packages/lib/string-utils.js+14 3 modified
    @@ -1,3 +1,5 @@
    +const Entities = require('html-entities').AllHtmlEntities;
    +const htmlentities = new Entities().encode;
     const stringUtilsCommon = require('./string-utils-common.js');
     
     const defaultDiacriticsRemovalMap = [
    @@ -294,16 +296,25 @@ function escapeHtml(s) {
     // keywords can either be a list of strings, or a list of objects with the format:
     // { value: 'actualkeyword', type: 'regex/string' }
     // The function surrounds the keywords wherever they are, even within other words.
    -function surroundKeywords(keywords, text, prefix, suffix) {
    +function surroundKeywords(keywords, text, prefix, suffix, options = null) {
    +	options = Object.assign({}, {
    +		escapeHtml: false,
    +	}, options);
    +
     	if (!keywords.length) return text;
     
    +	function escapeHtml(s) {
    +		if (!options.escapeHtml) return s;
    +		return htmlentities(s);
    +	}
    +
     	let regexString = keywords
     		.map(k => {
     			if (k.type === 'regex') {
    -				return stringUtilsCommon.replaceRegexDiacritics(k.valueRegex);
    +				return escapeHtml(stringUtilsCommon.replaceRegexDiacritics(k.valueRegex));
     			} else {
     				const value = typeof k === 'string' ? k : k.value;
    -				return stringUtilsCommon.replaceRegexDiacritics(stringUtilsCommon.pregQuote(value));
    +				return escapeHtml(stringUtilsCommon.replaceRegexDiacritics(stringUtilsCommon.pregQuote(value)));
     			}
     		})
     		.join('|');
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.