fix(comark): make renderMarkdown round-trips safe against injection - #376
Open
atinux wants to merge 6 commits into
Open
fix(comark): make renderMarkdown round-trips safe against injection#376atinux wants to merge 6 commits into
atinux wants to merge 6 commits into
Conversation
pre, mermaid, and YAML attribute blocks picked a fixed 3-backtick fence (switching to tildes only when the content contained backticks). Code containing a ~~~ line closed the fence early on re-parse, turning inert code into live document structure (e.g. ::alert components) — and the same applied to mermaid content and YAML props blocks. Add pickFence(): scan the content for the longest line-start run of each fence character and emit the shorter side, one character longer than any run present. Also stop growing mermaid content by a blank line per round trip.
comarkAttributes emitted string values as key="value" with no escaping, so a value containing a double quote closed the attribute on re-parse and the remainder became new attacker-chosen attributes (or a binding resolving frontmatter data). The props parser does not unescape backslashes, so prefer single quotes when the value has none; fall back to \"-escaping when both quote kinds are present.
A text node holding ::alert{...} (from an escaped or entity-encoded
source) was emitted verbatim by renderMarkdown, so a re-parse turned
literal text into a live component invocation; a bare :: line inside a
block component also closed the fence early.
escapeLeadingBlock now escapes lines starting with ':', and
escapeInline escapes ':' that can start an inline component (after
whitespace/start/*/_/[, before a name character) and '{' that opens an
attribute block.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
comark
@comark/angular
@comark/ansi
@comark/html
@comark/nuxt
@comark/react
@comark/svelte
@comark/vue
commit: |
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.
What
Three serializer hardening fixes (one commit each):
pickFence()chooses code fences that the content cannot close (pre, mermaid, YAML props blocks),comarkAttributeskeeps double quotes inside values inert, and text-node escaping now covers the Comark markers::/{.Why
A security scan found that inert content could become live structure after a documented parse →
renderMarkdown→ re-parse cycle: code containing a~~~line or mermaid content containing ``` broke out of its fence into live::alertmarkup, an attribute value with a double quote injected new attributes on re-parse, and text holding `::alert{...}` (from escaped or entity-encoded sources) re-parsed into a real component invocation. The quoting fix prefers single quotes because the props parser does not unescape backslashes.Known limitation: block math (
$$…$$) has no alternative delimiter, so math content containing$$still cannot round-trip — out of scope here.🤖 Prepared by an AI agent (OpenCode) from a security-audit findings list; commits are signed by the repository owner's key.