Soumettre #844847: vnote v3.20.1 Improper Neutralization of Alternate XSS Syntaxinformation

Titrevnote v3.20.1 Improper Neutralization of Alternate XSS Syntax
Description### Summary A stored cross-site scripting vulnerability exists in `vnotex/vnote` due to unsafe rendering of YAML frontmatter. The frontmatter content is inserted into the DOM using `innerHTML` without sanitization, and this code path bypasses the `protectFromXss` setting. In the default viewer context, successful exploitation allows attacker-controlled JavaScript to execute when a victim opens a malicious note, read local files from the `file://` context, and exfiltrate stolen data to a remote server. This is a high-severity client-side data disclosure issue. ### Details The issue is in the YAML frontmatter rendering path in [markdownit.js](https://github.com/vnotex/vnote/blob/master/src/data/extra/web/js/markdownit.js). Relevant code: ```javascript this.mdit.use(window.markdownitFrontMatter, (p_metaData) => { if (p_metaData) { let detailsNode = document.createElement('details'); detailsNode.classList.add('vx-frontmatter'); let summaryNode = document.createElement('summary'); summaryNode.textContent = 'Metadata'; detailsNode.appendChild(summaryNode); let preNode = document.createElement('pre'); preNode.innerHTML = p_metaData; detailsNode.appendChild(preNode); this.frontMatterNode = detailsNode; } }); ``` The vulnerable sink is: - [markdownit.js:198](https://github.com/vnotex/vnote/blob/master/src/data/extra/web/js/markdownit.js#L198) - `preNode.innerHTML = p_metaData;` The intended XSS protection does not cover this path: - [markdownit.js:209](https://github.com/vnotex/vnote/blob/master/src/data/extra/web/js/markdownit.js#L209) `protectFromXss` applies to the normal Markdown rendering flow, but the YAML frontmatter callback writes attacker-controlled content directly into the DOM before that protection can sanitize it. As a result, attacker-controlled HTML/JavaScript inside frontmatter executes even when `protectFromXss = true`. The impact is increased by how the viewer is configured: - Markdown is loaded with a `file://` base URL in [markdownviewwindow.cpp:516](https://github.com/vnotex/vnote/blob/7c59d0d061d30f8f1f57eab855b73d3b1f452df1/src/widgets/markdownviewwindow.cpp#L516) - Remote requests from local content are explicitly enabled in [markdownviewer.cpp:63](https://github.com/vnotex/vnote/blob/7c59d0d061d30f8f1f57eab855b73d3b1f452df1/src/widgets/editors/markdownviewer.cpp#L63) Relevant code: ```cpp settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true); ``` Because of this, attacker-controlled JavaScript can read local note files reachable from the viewer context and send the contents to an external server. ### PoC Tested on: - `vnote v3.20.1` - commit `4ecaf1e5` - default settings, including `protectFromXss = true` A working PoC script is available at Reproduction steps: 1. Run: ```bash python3 poc.py ``` 2. This generates malicious Markdown notes for staged testing. 3. Open the generated note in vnote. 4. Observe: - Stage 1: JavaScript executes immediately when the note is opened. - Stage 2: Another local Markdown file can be read via `fetch('file:///...')` and displayed. - Stage 3: The stolen content can be sent to a remote endpoint. A minimal malicious note looks like this: ```markdown --- title: <img src=x onerror="/* attacker-controlled JavaScript */"> --- # Normal content ``` No additional user interaction is required after opening the file. ### Impact This is a stored XSS vulnerability with a practical confidentiality impact in a desktop application context. Impacted users: - any user who opens an attacker-supplied Markdown note in vnote - users of shared notebook workflows such as Git sync, cloud-synced folders, or direct file sharing Confirmed impact: - stored JavaScript execution in the Markdown viewer - bypass of the `protectFromXss` security setting - local file read from the viewer `file://` context - remote exfiltration of stolen local note contents This issue should be treated as high severity because it allows silent theft of local notebook data from a malicious note file opened by the victim. ### Mitigation The vulnerability can be mitigated by ensuring YAML frontmatter is never inserted into the DOM using `innerHTML` without sanitization. Recommended fixes: - Replace `preNode.innerHTML = p_metaData;` with `preNode.textContent = p_metaData;` if plain-text display of frontmatter is sufficient. - If formatted rendering is required, sanitize frontmatter content with a strict allowlist before inserting it into the DOM. - Ensure the `protectFromXss` setting also applies to the frontmatter rendering path so that all rendered note content is covered consistently. - Re-evaluate the need for `QWebEngineSettings::LocalContentCanAccessRemoteUrls = true`, since this setting materially increases impact by enabling remote exfiltration from local content. - Consider adding additional hardening, such as a restrictive Content Security Policy for rendered note content where feasible. The most direct and reliable fix is to render frontmatter as text rather than HTML.
Utilisateur
 SISUBENY (UID 98681)
Soumission01/06/2026 14:01 (il y a 1 mois)
Modérer12/07/2026 07:36 (1 month later)
StatutAccepté
Entrée VulDB377834 [vnotex vnote jusqu’à 3.20.1 YAML Frontmatter markdownit.js p_metaData cross site scripting]
Points17

Do you want to use VulDB in your project?

Use the official API to access entries easily!