Repository navigation
Bump markdown-it from 14.3.0 to 14.3.3 - #270
Open
superbot-helper wants to merge 1 commit into
Open
superbot-helper wants to merge 1 commit into
superbot-helper wants to merge 1 commit into
Conversation
GHSA-gfr2-rv44-r23c (fixed in markdown-it 14.3.3 and 15.0.3): a link reference definition whose label or title is never closed is O(n^2) with default options. src/rules_block/reference.ts appends continuation lines with str += lineContent and then keeps indexing the accumulated string with str.charCodeAt and str.slice, so V8 flattens the cons-string once per line and one definition spanning n lines costs O(n^2); the work happens before the rule decides the definition is invalid. This repository renders user markdown server-side: GET /p/:id?surface=N runs server/app.ts renderPostPage -> server/richRender.ts renderMarkdown -> md.render (src) with default block rules. Through that route, a 400,009-byte unclosed link reference definition ("[a]: /u \"" + 200000 "x\n" lines) was measured on both trees, three runs of three samples, alternating trees: a median 5,122.7 ms at markdown-it 14.3.0 against 95.8 ms for the same 400,009 bytes with the leading "[" replaced by "x" (the same-length control), and a median 129.1 ms at 14.3.3. Absolute timings depend on machine load; the ordering between the crafted row and its same-byte-count control does not. package.json and package-lock.json move the single pin ^14.2.0 -> ^14.3.3 and its lock entry 14.3.0 -> 14.3.3; no application source changes.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Updates markdown-it from 14.3.0 to 14.3.3.
Fixes GHSA-gfr2-rv44-r23c — markdown-it's block reference rule appends continuation lines to a cons-string with
str += lineContentand then keeps indexing the accumulated string withstr.charCodeAt(pos)andstr.slice(...); V8 flattens the cons-string on the first index or slice after each append, copying everything collected so far, so one link reference definition whose label or title is never closed costs O(n^2) in the number of lines, and the work happens before the rule decides the definition is invalid. The route needs no option: html:false, linkify:true and the highlight callback in server/richRender.ts:185-189 leave the reference rule and its default block configuration untouched: a single GET /p/:id?surface=0&ver=1 through this repository's own server/app.ts Hono app and server/richRender.ts renderMarkdown, carrying a 400,009-byte markdown surface that is one unclosed link reference definition, took a median 5122.66 ms (4441.30-5506.92 ms) on markdown-it 14.3.0, while the same 400,009 bytes with the leading "[" replaced by "x" took a median 95.81 ms (89.05-102.94 ms) on the same tree and the crafted surface took a median 129.05 ms (114.20-169.23 ms) with 14.3.3.What this changes:
package.json— package.json:108: "markdown-it": "^14.2.0" -> "^14.3.3" (the only dependency change; the installed version moves 14.3.0 -> 14.3.3).package-lock.json— package-lock.json: root packages[""].dependencies["markdown-it"] and node_modules/markdown-it move to ^14.3.3 / 14.3.3 with the 14.3.3 tarball and integrity hash; no other package entry changes.How to verify:
Measured before and after, same code path, same payload
Both trees are this repository at
a3b18af5a77f40889ec1f06359a277ccc61310ff; the only difference is package.json and package-lock.json, which move markdown-it 14.3.0 to 14.3.3. Each row publishes one markdown surface through this repository's ownPOST /api/postsand then times oneGET /p/:id?surface=0&ver=1through the sameserver/app.tsHono app andserver/richRender.tsrenderMarkdown; each sample runs in a fresh Node process and the first render in a process pays a warmup that every row and both trees pay. Nine samples per row per tree, three runs, alternating trees sample by sample.[a]: /u "+ 200,000x\nlines (400,009 B)[replaced byx(400,009 B)hello **world**(16 B)The control carries the same 400,009 bytes, the same 200,001 lines and the same link-title text as the crafted payload: only the
[that opens the block reference definition becomesx. Both rows render to the same 407,470-byte page. On the base tree the crafted row is about 53x its control; with 14.3.3 the crafted row costs 129.05 ms against 95.53 ms for its control.Absolute timings depend on machine load and on the ~80 ms first-render warmup each fresh process pays before the timed request (visible in the baseline row); the ordering between the crafted row and its same-byte-count control does not.
Where the cost is
server/app.ts:1213mountsPOST /api/posts, which validates and stores amarkdownsurface whose body is the request JSON (server/postSurfaces.ts, 2 MiB surface cap).server/app.ts:1672mountsGET /p/:id(and:1671the legacy aliasGET /s/:id) torenderPostPage(defined at:1568); for a surface of kindmarkdownit callsrenderMarkdown(surface)atserver/app.ts:1655-1656.server/richRender.ts:176renderMarkdownconstructsnew MarkdownIt({ html: false, linkify: true, highlight })at:185-189and callsmd.render(src)at:199.Inside markdown-it 14.3.0,
src/rules_block/reference.tspulls continuation lines withstr += lineContent(lines 74, 83, 100, 133 and 150) and then keeps indexing the accumulated string withstr.charCodeAt(pos)in the label and whitespace loops andstr.slice(...)inparseLinkTitle; V8 represents+=as a cons-string and the next index or slice flattens it, copying everything collected so far, so one definition spanning n lines costs O(n^2). The work happens before the rule decides the definition is invalid. the advisory's own isolation showsmd.disable('reference')makes the same input linear, and in this packet's control the same bytes without the leading[never enter the rule at all.The fix in 14.3.3 (
48fbc46,d99f488) tracks positions instate.srcinstead of building the string and bounds the label and title scan, so the crafted 400,009 bytes render in the same time as their control.Scope
package.json:markdown-it^14.2.0->^14.3.3, one line.package-lock.json: the root dependency entry and thenode_modules/markdown-itentry move 14.3.0 -> 14.3.3 with the registry tarball and integrity hash for 14.3.3; no other lock entry changes.No application source, template, config or test changes. The renderer API used here (
renderMarkdown,new MarkdownIt) is unchanged between the two patch releases.What this does not claim
Only the 14.3.0 -> 14.3.3 move was measured; the advisory also covers 14.1.0..14.3.2 and 15.0.0..15.0.2, and trees on those versions were not measured here.
The measurements are single-request costs in milliseconds through the application's own in-process Hono
app.fetchpipeline (the samecreateApp,SqlStoreandrenderMarkdownmodules the Node server runs), not a live HTTP server, a Worker deployment or a concurrent-request throughput figure. The ceiling is one request's wall-clock time inside one Node process: the crafted row is ~5.1 s at base and ~0.13 s with this change, absorbed by that process's event loop.Absolute timings depend on machine load; only the ordering between a crafted row and its same-byte-count control is claimed.
The two sibling markdown-it advisories that also cover 14.3.0 (GHSA-r7fv-28h4-cvq7 smartquotes and GHSA-vfgh-jcmw-g37q inline HTML) need
typographer: trueandhtml: true, which this renderer does not enable, so this packet does not claim to exercise them.Crafted and same-byte control markdown were measured through this repository's own /p/:id route: 5.1 s on markdown-it 14.3.0 vs 96 ms for the control, 0.13 s on 14.3.3.
Automated security patch from Superbot.