This CVE reveals a semantic mismatch between how justhtml parses HTML content and how its to_markdown() function serializes that same content. The parser correctly decodes HTML entities according to the HTML spec — including the special RCDATA/RAWTEXT rules for elements like <title> and <textarea>. When parsing <script> inside an RCDATA element, the parser decodes it to literal text <script>, which renders harmlessly in HTML output. However, to_markdown() receives this decoded text and emits it as-is, without re-escaping the angle brackets for Markdown contexts. The result is raw HTML injection when that Markdown is subsequently rendered as HTML by a downstream system.

The critical failure is contextual: developers reasonably expect that content already processed as safe HTML remains safe through format transformations. The library's API design — where the same parsed object can output to HTML or Markdown — creates an implicit promise that safety invariants carry across output formats. That promise is false. The parser knows the provenance of its decoded characters; the Markdown serializer does not.

For defenders, the practical implications are: first, treat to_markdown() output as untrusted and run it through a separate sanitization layer before rendering in any HTML context — do not assume the library maintains your security contract. Second, audit any pipelines where justhtml extracts content from RCDATA elements and passes the result to Markdown consumers; this is the most likely integration point where the vulnerability manifests. Third, review your downstream rendering stack — if Markdown is being converted to HTML anywhere in your pipeline, that conversion must include its own escaping step, regardless of what justhtml emitted.

The severity reflects the bridging vector this creates: content explicitly whitelisted as safe for HTML output by upstream sanitizers can now reach contexts where it was never intended to go. This is an abstraction leak, not merely a missing feature — the library presents a clean format conversion but secretly depends on output-context assumptions it never exposes.