TL;DR:
MathJax up to v2.7.9 contains two Regular expression Denial-of-Service (ReDoS) vulnerabilities in MathJax.js, specifically via the components and markdownPattern regular expressions. However, the MathJax team disputes the severity, saying these patterns don't process user input directly in most cases. Below, we explain the details, show real code snippets, and link to all original discussions.

What Is CVE-2023-39663?

MathJax is a very popular open-source JavaScript display engine for LaTeX, MathML, and AsciiMath notation. Used widely in education and science, it helps websites show fancy math formulas. In June 2023, security researchers identified a potential Denial-of-Service vulnerability caused by inefficient regular expressions in MathJax.js.

Vulnerability Type:
Regular expression Denial of Service (ReDoS)

Affected Versions:
MathJax ≤ 2.7.9

Components Impacted:

What’s a ReDoS Attack?

ReDoS attacks exploit "evil" regular expressions that take a long time to process certain input. Attackers construct input strings that make the regex engine backtrack again and again, hogging CPU time and resources, which can freeze or crash servers.

Example:
If a regex like /^([a-z]+)+$/ is fed a string like "aaaaaaaaaaaaaaaaaaaaab", the regex engine takes a long time to realize "b" breaks the pattern. Multiply that delay many times, and you have a denial-of-service condition.

1. The components Pattern

var components = /([^\s'"=<>`]+)(.*?)=(["'])(.*?)\3/g;

2. The markdownPattern

var markdownPattern = /(\[.*\]\(.*\))/g;

Both use *greedy* patterns like (.*?), .*, or nested quantifiers, potentially causing backtracking.

Let’s look at a small test

// Simulate a long, malicious input string
let badString = "a=".repeat(50000) + '"b';

// Apply the regex
let start = Date.now();
components.exec(badString);
let end = Date.now();

console.log("Milliseconds taken:", end - start);

If the regex is malicious, the time grows with the length of badString, which could freeze the browser or server.

Theoretical Exploit

If a user can make MathJax process a specially crafted string (like a bad Markdown link or HTML attribute list), they could freeze the browser or overload a server.

Simple Example Input

[aaaaaaaa...aaaaa(break)](bbbbbbbbbbbbbb)

or

<tag a="aaaaaaaa...aaaaa">

MathJax might hang when parsing these if ReDoS is possible.

> Note: The vendor argues these regexes _do not_ parse arbitrary user input, so *real-world exploitability* is low unless you manually insert input in a non-standard way.

The MathJax team disputes the vulnerability claim

> "The regular expressions in question are only used for controlled data, not arbitrary user input. Therefore, there is no practical way for an attacker to exploit this in normal operation. We do not consider this a real-world vulnerability."

- GitHub issue: "Possible ReDoS via Markdown Parser"
- NVD entry: CVE-2023-39663
- MathJax source code: MathJax.js on GitHub

Higher Risk (custom scenarios):

If you *customize* MathJax or write code that processes unvalidated user input via these regexes, you might be exposed.

References

- 🔗 CVE-2023-39663 NVD Report
- 🔗 MathJax GitHub Issue #2897
- 🔗 MathJax Source 2.7.9
- 🔗 OWASP ReDoS Cheat Sheet

Summary Table

| Version | Vulnerable? | Fixed? | Real-World Exploit? |
|-----------------|-------------|--------|-----------------------------|
| ≤ MathJax 2.7.9 | Yes | No | Unlikely, per vendor |
| MathJax 3.x+ | No | Yes | Not affected |

Conclusion

CVE-2023-39663 highlights the ongoing risk of ReDoS in JavaScript libraries. In MathJax's case, the practical risk is very low because the patterns don’t parse user data by default. But if you modify MathJax or handle raw user input with these regexes, caution is advised.
Always validate input and update dependencies.
For peace of mind, upgrade to the latest MathJax (3.x+)—it’s safer and better in many ways.


*Stay secure, code safe, and beware those evil regexes!*

Timeline

Published on: 08/29/2023 20:15:09 UTC
Last modified on: 11/07/2023 04:17:36 UTC