CVE-2026-46650 Overview
Joplin is an open-source note-taking and to-do application that organizes notes into notebooks. A cross-site scripting (XSS) vulnerability [CWE-79] affects Joplin versions prior to 3.7.2. The isAcceptedUrl() function in packages/renderer/htmlUtils.ts uses an unanchored regular expression when validating internal resource URLs. Attackers can craft a javascript: URL containing a matching 32-character path fragment that bypasses validation and is emitted into an HTML note's link. A low-privileged Joplin Server user can publish the crafted HTML note as a public share to reach other users.
Critical Impact
Successful exploitation runs attacker script in the Joplin Server origin, exposing page-visible content and enabling authenticated same-origin requests on behalf of signed-in victims.
Affected Products
- Joplin Server prior to version 3.7.2
- Joplin Desktop prior to version 3.7.2
- Joplin Mobile prior to version 3.7.2
Discovery Timeline
- 2026-09-21 - CVE-2026-46650 published to NVD
- 2026-09-23 - Last updated in NVD database
Technical Details for CVE-2026-46650
Vulnerability Analysis
The vulnerability resides in the URL validation logic used by Joplin's HTML note renderer. isAcceptedUrl() in packages/renderer/htmlUtils.ts matches internal resource URLs with the pattern :\/[0-9a-zA-Z]{32} without anchoring the expression. Because the regex is unanchored, any URL containing that 32-character path fragment anywhere in the string is accepted, including URLs that begin with the javascript: scheme. The malicious URL is then written directly into the rendered HTML link.
Exploitation requires user interaction. Modern Chrome and Firefox block javascript: navigation in new tabs, so ordinary left-clicks are stopped. Demonstrated execution requires middle-click or Open in new tab in an older or non-hardened browser. When execution succeeds, the script runs in the Joplin Server origin.
Root Cause
The defective validation stems from missing anchor tokens in the regular expression. The original check accepted any string containing :/ followed by 32 alphanumeric characters, rather than requiring the URL to start with that construct. The vendor patch anchors the pattern with ^ and $ and constrains what may follow the resource identifier.
Attack Vector
A low-privileged authenticated Joplin Server user creates an HTML note containing a link with a javascript: URL that embeds the 32-character token required to satisfy the regex. The attacker publishes the note as a public share. A victim opens the shared note and activates the poisoned link with middle-click or Open in new tab. The injected script executes in the Joplin Server origin, reads DOM content, and issues authenticated same-origin requests.
// Security patch in packages/renderer/htmlUtils.ts
// Fix XSS vulnerability in HTML notes (#15435)
url.startsWith('http://') ||
url.startsWith('mailto:') ||
url.startsWith('joplin://') ||
- !!url.match(/:\/[0-9a-zA-Z]{32}/) ||
+ !!url.match(/^:\/[0-9a-zA-Z]{32}(\/.*)?$/) ||
// We also allow anchors but only with a specific set of a characters.
// Fixes https://github.com/laurent22/joplin/issues/8286
!!url.match(/^#[a-zA-Z0-9-]+$/)) return true;
Source: GitHub Commit 9fdc2d4
Detection Methods for CVE-2026-46650
Indicators of Compromise
- HTML notes containing anchor tags whose href attribute begins with javascript: and embeds a 32-character alphanumeric token preceded by :/.
- Public shares published by low-privileged accounts that were not previously associated with content publishing activity.
- Outbound requests from a user's browser to the Joplin Server origin immediately after opening a shared note in a new tab.
Detection Strategies
- Inspect stored HTML note content for javascript: URL schemes inside href attributes and flag matches for review.
- Correlate share-creation events with subsequent authenticated same-origin API calls originating from viewers of that share.
- Enable Content Security Policy (CSP) reporting on the Joplin Server origin to surface blocked inline script and javascript: navigations.
Monitoring Recommendations
- Track the version of Joplin Server, Desktop, and Mobile clients in use across the environment and alert on instances running below 3.7.2.
- Monitor Joplin Server access logs for unexpected authenticated requests made from public share sessions.
- Review new public share creations from accounts with minimal historical activity as a behavioral signal.
How to Mitigate CVE-2026-46650
Immediate Actions Required
- Upgrade all Joplin Server, Desktop, and Mobile installations to version 3.7.2 or later.
- Audit existing public shares for HTML notes containing javascript: URLs and unpublish suspect content.
- Restrict the ability to create public shares to trusted accounts until upgrades complete.
Patch Information
The fix is available in Joplin 3.7.2. The corrective change anchors the internal-resource regular expression in isAcceptedUrl() so that only URLs whose entire structure matches ^:/[0-9a-zA-Z]{32}(/.*)?$ are accepted. Details are published in GitHub Security Advisory GHSA-x9vj-jrqf-9wcm and merged via GitHub Pull Request #15435.
Workarounds
- Disable public sharing on Joplin Server until the upgrade is applied.
- Ensure end users access Joplin shares from current versions of Chrome or Firefox, which block javascript: navigation in new tabs.
- Deploy a strict Content Security Policy on the Joplin Server origin that forbids inline script execution.
# Verify installed Joplin Server version and upgrade
joplin --version
# Example Docker upgrade path
docker pull joplin/server:3.7.2
docker stop joplin-server && docker rm joplin-server
docker run -d --name joplin-server -p 22300:22300 joplin/server:3.7.2
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

