CVE-2023-37298: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Joplin before 2.11.5 allows XSS via a USE element in an SVG document.
CWE description: 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.
CVSS v3 base score: 6.1
Published: 2023-06-30T15:15Z
Repository: https://github.com/laurent22/joplin
Language: TypeScript
Files changed: packages/app-cli/tests/MdToHtml.ts, packages/app-cli/tests/md_to_html/sanitize_15.html, packages/app-cli/tests/md_to_html/sanitize_15.md, packages/renderer/htmlUtils.ts
Commit date: 2023-05-17 16:00:24 +0100
Commit message: Desktop, Mobile: Security: Disable SVG tag support in editor to prevent XSS

Diff: diff --git a/packages/app-cli/tests/MdToHtml.ts b/packages/app-cli/tests/MdToHtml.ts
index 44831ace44..cb36e6b519 100644
--- a/packages/app-cli/tests/MdToHtml.ts
+++ b/packages/app-cli/tests/MdToHtml.ts
@@ -33,11 +33,11 @@ describe('MdToHtml', () => {
 			if (mdFilename.indexOf('.md') < 0) continue;
 
 			const mdFilePath = `${basePath}/${mdFilename}`;
 			const htmlPath = `${basePath}/${filename(mdFilePath)}.html`;
 
-			// if (mdFilename !== 'sanitize_9.md') continue;
+			if (mdFilename !== 'sanitize_15.md') continue;
 
 			const mdToHtmlOptions: any = {
 				bodyOnly: true,
 			};
 
diff --git a/packages/app-cli/tests/md_to_html/sanitize_15.html b/packages/app-cli/tests/md_to_html/sanitize_15.html
new file mode 100644
index 0000000000..d6d42d0761
--- /dev/null
+++ b/packages/app-cli/tests/md_to_html/sanitize_15.html
@@ -0,0 +1 @@
+<use href="data:image/svg+xml,&lt;svg id=&apos;x&apos; xmlns=&apos;http://www.w3.org/2000/svg&apos;&gt;&lt;image href=&apos;asdf&apos; onerror=&apos;top.require(`child_process`).execSync(`calc.exe`)&apos; /&gt;&lt;/svg&gt;#x" class="jop-noMdConv">
\ No newline at end of file
diff --git a/packages/app-cli/tests/md_to_html/sanitize_15.md b/packages/app-cli/tests/md_to_html/sanitize_15.md
new file mode 100644
index 0000000000..e470479e16
--- /dev/null
+++ b/packages/app-cli/tests/md_to_html/sanitize_15.md
@@ -0,0 +1 @@
+<svg><use href="data:image/svg+xml,&lt;svg id='x' xmlns='http://www.w3.org/2000/svg'&gt;&lt;image href='asdf' onerror='top.require(`child_process`).execSync(`calc.exe`)' /&gt;&lt;/svg&gt;#x" />
\ No newline at end of file
diff --git a/packages/renderer/htmlUtils.ts b/packages/renderer/htmlUtils.ts
index 7b5906d73f..33da16c700 100644
--- a/packages/renderer/htmlUtils.ts
+++ b/packages/renderer/htmlUtils.ts
@@ -181,21 +181,25 @@ class HtmlUtils {
 		// attacks. See sanitize_11.md
 		let disallowedTagDepth = 0;
 
 		// The BASE tag allows changing the base URL from which files are
 		// loaded, and that can break several plugins, such as Katex (which
-		// needs to load CSS files using a relative URL). For that reason
-		// it is disabled. More info:
-		// https://github.com/laurent22/joplin/issues/3021
+		// needs to load CSS files using a relative URL). For that reason it is
+		// disabled. More info: https://github.com/laurent22/joplin/issues/3021
 		//
-		// "link" can be used to escape the parser and inject JavaScript.
-		// Adding "meta" too for the same reason as it shouldn't be used in
-		// notes anyway.
+		// "link" can be used to escape the parser and inject JavaScript. Adding
+		// "meta" too for the same reason as it shouldn't be used in notes
+		// anyway.
+		//
+		// There are too many issues with SVG tags and to handle them properly
+		// we should parse them separately. Currently we are not so it is better
+		// to disable them. SVG graphics are still supported via the IMG tag.
 		const disallowedTags = [
 			'script', 'iframe', 'frameset', 'frame', 'object', 'base',
 			'embed', 'link', 'meta', 'noscript', 'button', 'form',
 			'input', 'select', 'textarea', 'option', 'optgroup',
+			'svg',
 		];
 
 		const parser = new htmlparser2.Parser({
 
 			onopentag: (name: string, attrs: Record<string, string>) => {

Vulnerable code: 			// if (mdFilename !== 'sanitize_9.md') continue;
		// needs to load CSS files using a relative URL). For that reason
		// it is disabled. More info:
		// https://github.com/laurent22/joplin/issues/3021
		// "link" can be used to escape the parser and inject JavaScript.
		// Adding "meta" too for the same reason as it shouldn't be used in
		// notes anyway.
Fixed code: 			if (mdFilename !== 'sanitize_15.md') continue;
<use href="data:image/svg+xml,&lt;svg id=&apos;x&apos; xmlns=&apos;http://www.w3.org/2000/svg&apos;&gt;&lt;image href=&apos;asdf&apos; onerror=&apos;top.require(`child_process`).execSync(`calc.exe`)&apos; /&gt;&lt;/svg&gt;#x" class="jop-noMdConv">
<svg><use href="data:image/svg+xml,&lt;svg id='x' xmlns='http://www.w3.org/2000/svg'&gt;&lt;image href='asdf' onerror='top.require(`child_process`).execSync(`calc.exe`)' /&gt;&lt;/svg&gt;#x" />
		// needs to load CSS files using a relative URL). For that reason it is
		// disabled. More info: https://github.com/laurent22/joplin/issues/3021
		// "link" can be used to escape the parser and inject JavaScript. Adding
		// "meta" too for the same reason as it shouldn't be used in notes
		// anyway.
		//
		// There are too many issues with SVG tags and to handle them properly
		// we should parse them separately. Currently we are not so it is better
		// to disable them. SVG graphics are still supported via the IMG tag.
			'svg',