CVE-2026-77088 in justhtml's to_markdown() function is a code injection vulnerability disguised as a format conversion bug. The function generates Markdown that, when rendered by a downstream Markdown parser, can execute attacker-controlled syntax — the same family as SQL injection, but with three actors instead of two: attacker supplies HTML, justhtl generates Markdown, and a compliant renderer executes it.
The attack mechanism is precise. Markdown treats blank lines as hard block boundaries — a core design principle that terminates inline constructs like code spans. An attacker submitting HTML containing blank lines within what should be inline content (e.g., `<code>line one
injected</code>`) produces Markdown where the blank line breaks the code span, allowing the text after it to render as unescaped Markdown syntax. The vulnerability lives in the gap between what the library emits and how downstream parsers interpret it: the output contract was never bounded against re-parsing.
The blast radius is deployment-dependent, and this is where defenders must think carefully. A static site generator converting trusted authored HTML faces trivial risk. A content management system accepting user-submitted HTML, piping it through to_markdown(), and rendering to other users has an entirely different risk topology. CVSS 6.1 measures the mechanism, not the pipeline exposure — many real-world deployments likely wire these three components together in vulnerable configurations, but the evidence base is thin.
This vulnerability belongs to a documented lineage. The blank-line-as-attack-trigger pattern appeared in XML parsers and email MIME boundary handling circa 2002-2005, when browsers and sanitizers had inconsistent blank-line handling that allowed crafted inputs to escape attribute contexts into element contexts. The pattern recurs across format converters because each layer patches the symptom in isolation without recognizing the inherited assumption: that blank lines don't carry semantic weight. The next format-conversion library to popularize will likely surface the same mutation — this isn't a one-off but a structural antipattern.
For immediate action: audit whether your deployment passes user-controlled HTML through to_markdown() to a Markdown renderer. If so, treat the output as untrusted until you add explicit escaping or switch to a library that emits opaque output. The patch (escaping blank lines in code spans) fixes this specific vector but doesn't close the architectural gap — format converters with unbounded output contracts will continue accumulating similar vulnerabilities.