| शीर्षक | vnote v3.20.1 Improper Neutralization of Alternate XSS Syntax |
|---|
| विवरण | ### 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.
|
|---|
| उपयोगकर्ता | SISUBENY (UID 98681) |
|---|
| सबमिशन | 01/06/2026 02:01 PM (1 महीना पहले) |
|---|
| संयम | 12/07/2026 07:36 AM (1 month later) |
|---|
| स्थिति | स्वीकृत |
|---|
| VulDB प्रविष्टि | 377834 [vnotex vnote तक 3.20.1 YAML Frontmatter markdownit.js p_metaData क्रॉस साइट स्क्रिप्टिंग] |
|---|
| अंक | 17 |
|---|