Stored XSS FOUND! In Many Notes, The Best Note Taking APP!

Featured image

How I Found a Stored XSS in Markdown Rendering

Severity: High (CVSS 7.3)


The Discovery

I was testing the markdown rendering feature in the Many Notes application when something caught my eye. It looked like the application was running user content through a markdown parser and then trying to clean it with DOMPurify. On paper, that sounds safe enough. In practice, it wasn’t.

After a couple of quick checks, I realized I could sneak in a script tag and get it to execute. That meant the app was vulnerable to a classic stored XSS.


Where It Happens

The issue shows up when viewing files like this:

http://localhost/files/2?path=test2.md

If you upload a malicious markdown file, the contents get stored and later displayed without proper sanitization.


Under the Hood

Here’s the relevant code path:

if (options.content) {
    content = DOMPurify.sanitize(
        markedService.parse(options.content),
    );
}

The problem is that DOMPurify doesn’t catch everything. It’s good at blocking obvious stuff, but more creative payloads (SVG tricks, DOM clobbering, mutation XSS) can still get through.


Proof of Concept

The simplest test payload worked right away:

<script>alert("Cyber Ducky was Here")</script>

Open the file in the browser, and sure enough, the alert popped.


Why It Matters

This isn’t just a harmless pop-up. Once an attacker has XSS in the application, they can:


Fixing It

If I were patching this, here’s what I’d do right away:


Timeline


Closing Thoughts

This was a straightforward find, but it highlights a bigger point: relying solely on client-side libraries like DOMPurify isn’t enough. XSS is sneaky, and even well-known tools can miss certain payloads.

Thank You Bruno at Many Notes for getting this patched ASAP!
Here is the GitHub Credit given: https://github.com/brufdev/many-notes/releases/tag/v0.10.2

Advertisement