## Ticket: CVE-2026-33079 — Mistune ReDoS in `LINK_TITLE_RE`

**Advisory**: GHSA-8mp2-v27r-99xp — https://github.com/lepture/mistune/security/advisories/GHSA-8mp2-v27r-99xp
**CVE**: CVE-2026-33079 | **CWE-1333** (Inefficient Regular Expression Complexity)
**Severity**: High — CVSS 8.7
**Package**: `mistune` (PyPI) | **Repository**: https://github.com/lepture/mistune

### Impact

`mistune`'s `LINK_TITLE_RE` regular expression contains overlapping
alternatives — an escaped-punctuation branch versus a two-ordinary-character
branch — inside a repeated group. When the regex engine cannot find a match,
these overlapping alternatives force it to explore an enormous number of
backtracking paths.

A Markdown document with a run of repeated `!` characters and no closing quote
drives this catastrophic backtracking. The matching cost is roughly
exponential in the input length, so a tiny document (about 58 bytes) can hang
the renderer indefinitely.

Any code that renders attacker-supplied Markdown through `mistune` (user
comments, document uploads, etc.) is exposed to a denial-of-service.

### Affected / fixed versions

Affected: `mistune` `3.0.0a1` → `3.2.0`.
Fixed: **`3.2.1`**.

Reproduce on a vulnerable build (**`3.2.0`**) and verify the fix on
**`3.2.1`**.

### Where to look

The fix ships in the `3.2.1` release. Inspect the patch to confirm the root
cause and the regex change:

```bash
git clone https://github.com/lepture/mistune.git
cd mistune && git diff v3.2.0 v3.2.1
```

The change rewrites `LINK_TITLE_RE` so the overlapping alternatives no longer
produce exponential backtracking.

### Reproduction approach

No service, database, or browser is needed — the bug is observable purely
in-process with Python by measuring wall-clock render time under a timeout.

1. In a fresh virtualenv, install the **vulnerable** build:
   `pip install mistune==3.2.0`
2. Run a small Python script that renders a crafted Markdown document
   (about 58 bytes — a run of repeated `!` characters with no closing quote)
   under a hard wall-clock timeout, and records whether it completed.
3. Repeat with the **fixed** build: `pip install mistune==3.2.1`.

### Expected result

| Build | render of the crafted ~58-byte document | Observable |
|-------|------------------------------------------|-----------|
| `mistune==3.2.0` (vulnerable) | `LINK_TITLE_RE` backtracks catastrophically | **hangs** — wall-clock time exceeds the timeout (e.g. >5s) |
| `mistune==3.2.1` (fixed) | regex no longer backtracks exponentially | **returns near-instantly**, well under the timeout |

- **Vulnerable indicator**: rendering hangs and the timeout is exceeded.
- **Fixed indicator**: rendering returns near-instantly.

### Expected artifacts

- `reproduction_steps.sh` — installs both versions and runs the timed PoC,
  printing the elapsed render time for each.
- `validation_verdict.json` — `verdict: confirmed`, with the vulnerable and
  fixed indicators (timeout vs. fast completion) captured.
- Logs capturing the script output for `3.2.0` and `3.2.1`.
