chore(deps): update dependency markdown-it to v14.2.0 [security]
This PR contains the following updates:
| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [markdown-it](https://redirect.github.com/markdown-it/markdown-it) | [`14.1.1` → `14.2.0`](https://renovatebot.com/diffs/npm/markdown-it/14.1.1/14.2.0) |  |  |
---
### markdown-it: Quadratic complexity DoS in smartquotes rule via replaceAt string operations
[CVE-2026-48988](https://nvd.nist.gov/vuln/detail/CVE-2026-48988) / [GHSA-6v5v-wf23-fmfq](https://redirect.github.com/advisories/GHSA-6v5v-wf23-fmfq)
<details>
<summary>More information</summary>
#### Details
##### Summary
A quadratic time complexity vulnerability exists in markdown-it's smartquotes rule (enabled via the `typographer: true` option). An attacker can craft a markdown input consisting of consecutive quotation marks that causes the parser to consume excessive CPU time, leading to denial of service.
##### Details
The vulnerability is in the `replaceAt()` helper function used by the smartquotes rule in `lib/rules_core/smartquotes.mjs`:
```javascript
function replaceAt (str, index, ch) {
return str.slice(0, index) + ch + str.slice(index + 1)
}
```
When markdown-it processes a text token containing many quotation marks (either `"` or `'`) with `typographer: true`, the smartquotes rule iterates through each quote character and calls `replaceAt()` to substitute it with a typographic (curly) quote. Each call to `replaceAt()` creates three new string slices and concatenates them, which is an O(n) operation where n is the length of the string.
Since this is called once per quote character in the token, and there are n quote characters, the total time complexity becomes O(n^2).
The root cause is that the smartquotes rule modifies `token.content` in place using string slicing rather than building the result incrementally. The `process_inlines()` function (line 14) processes each quote in the text token, and for matching quote pairs, calls `replaceAt()` on both the opening and closing token's content (lines 151-152). When the entire input is a single text token of quote characters, this results in quadratic behavior.
##### PoC
```javascript
const md = require('markdown-it');
const instance = md({ typographer: true });
// 160,000 consecutive double-quote characters
const payload = '"'.repeat(160000);
console.time('render');
instance.render(payload);
console.timeEnd('render');
// Output: render: ~21000ms (21 seconds)
// Compare with typographer disabled:
const safe = md({ typographer: false });
console.time('render-safe');
safe.render(payload);
console.timeEnd('render-safe');
// Output: render-safe: ~8ms
```
Measured timing on a modern system:
- 10,000 quotes: ~19ms
- 20,000 quotes: ~51ms
- 40,000 quotes: ~212ms
- 80,000 quotes: ~5,430ms
- 160,000 quotes: ~21,198ms
The scaling is clearly superlinear (quadratic), with the 80K->160K step showing a ~3.9x increase for a 2x input increase, consistent with O(n^2).
##### Impact
Applications that render user-supplied markdown with `typographer: true` are vulnerable to denial of service. An attacker can submit a relatively small payload (160KB of quote characters) that causes the server to spend over 21 seconds processing a single request. Repeated submissions can exhaust server CPU resources and prevent legitimate users from being served.
The impact is mitigated by the fact that the `typographer` option defaults to `false` and must be explicitly enabled. However, the typographer feature is commonly enabled in production applications that want smart typography, and the markdown-it documentation prominently suggests enabling it.
A suggested fix would be to replace the `replaceAt()` approach with an array-based or StringBuilder-style approach that collects all replacements and applies them in a single pass, reducing the time complexity to O(n).
#### Severity
- CVSS Score: 5.3 / 10 (Medium)
- Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L`
#### References
- [https://github.com/markdown-it/markdown-it/security/advisories/GHSA-6v5v-wf23-fmfq](https://redirect.github.com/markdown-it/markdown-it/security/advisories/GHSA-6v5v-wf23-fmfq)
- [https://github.com/advisories/GHSA-6v5v-wf23-fmfq](https://redirect.github.com/advisories/GHSA-6v5v-wf23-fmfq)
This data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-6v5v-wf23-fmfq) ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).
</details>
---
### Release Notes
<details>
<summary>markdown-it/markdown-it (markdown-it)</summary>
### [`v14.2.0`](https://redirect.github.com/markdown-it/markdown-it/blob/HEAD/CHANGELOG.md#1420---2026-05-24)
[Compare Source](https://redirect.github.com/markdown-it/markdown-it/compare/14.1.1...14.2.0)
##### Added
- `isPunctCharCode` to utilities.
##### Fixed
- Don't end HTML comment blocks on a blank line, [#​1155](https://redirect.github.com/markdown-it/markdown-it/issues/1155).
- Properly recognize astral chars (surrogates) in delimiter scans for
emphasis-like markers, [#​1072](https://redirect.github.com/markdown-it/markdown-it/issues/1072). Big thanks to [@​tats-u](https://redirect.github.com/tats-u) for his global efforts
with improving CJK support.
- Preserve unicode whitespaces when trimm headings/paragraphs, [#​1074](https://redirect.github.com/markdown-it/markdown-it/issues/1074).
- More strict entities decode to avoid false positives `;`, [#​1096](https://redirect.github.com/markdown-it/markdown-it/issues/1096).
- Restore block parser state on fail in `lheading` rule, [#​1131](https://redirect.github.com/markdown-it/markdown-it/issues/1131).
##### Security
- Fixed poor smartquotes perfomance on > 70k quotes in single block
- Bumped linkify-it to 5.0.1 with fixed potential perfomance issues.
</details>
---
### Configuration
📅 **Schedule**: (UTC)
- Branch creation
- At any time (no schedule defined)
- Automerge
- At any time (no schedule defined)
🚦 **Automerge**: Enabled.
♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/MoomFE/mixte).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMTkuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIxOS4wIiwidGFyZ2V0QnJhbmNoIjoiZGV2IiwibGFiZWxzIjpbXX0=-->
合并状态:未合并 2 条评论