renderEmail() in inline/LinkTrait.php (lines 194-198, unchanged since 2014-10-10) escapes the parsed email address with htmlspecialchars(..., ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8'), which does not escape double-quote characters, and then interpolates it into a double-quoted HTML href attribute:
protected function renderEmail($block)
{
$email = htmlspecialchars($block[1], ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8');
return "<a href=\"mailto:$email\">$email</a>";
}
The email autolink regex in parseLt() (/^<([^\s>]*?@[^\s]*?\.\w+?)>/) allows " in the local part. Input <"onmouseover=alert(1)//@x.y> is parsed as an email autolink and rendered as:
<p><a href="mailto:"onmouseover=alert(1)//@x.y">"onmouseover=alert(1)//@x.y</a></p>
Verified with html5lib (faithful HTML5 tokenizer): the browser parses this as <a href="mailto:" onmouseover='alert(1)//@x.y"'> — a live onmouseover event handler. On hover, alert(1) executes.
That CVE (DISPUTED) was about fenced-code-block raw HTML passthrough. This bug is not raw HTML passthrough: parseLt() routes <...@x.y> to renderEmail() before the raw-HTML fallback (parseInlineHtml). The broken HTML is generated by the library from a markdown-syntax autolink, not passed through from user HTML. I acknowledge the maintainer's documented position that output should be filtered with HTML Purifier; this is offered as an escaping defect the library itself introduces.
Affected
Markdown, MarkdownExtra, GithubMarkdown (shared LinkTrait)
- Versions: ≥1.1.2 through 1.2.1 and master (
2b2461b)
- No fix exists.
CVSS v3.1
5.8 Medium — CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
Constraint: the injected portion cannot contain whitespace (regex excludes \s), so the practical payload is interaction-required (onmouseover); no no-interaction payload found.
Suggested fix
protected function renderEmail($block)
{
$email = htmlspecialchars($block[1], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
return "<a href=\"mailto:$email\">$email</a>";
}
Reproduction
<?php
spl_autoload_register(function ($c) {
$f = '/path/to/cebe/markdown/' . str_replace('\\', '/', substr($c, 14)) . '.php';
if (is_file($f)) require $f;
});
$p = new cebe\markdown\Markdown();
echo $p->parse('<"onmouseover=alert(1)//@x.y>'), PHP_EOL;
Output:
<p><a href="mailto:"onmouseover=alert(1)//@x.y">"onmouseover=alert(1)//@x.y</a></p>
Independent discovery during a security audit. Verified novel: OSV empty, GitHub Advisory DB empty, no prior issue/comment mentions renderEmail/mailto/ENT_NOQUOTES.
renderEmail()ininline/LinkTrait.php(lines 194-198, unchanged since 2014-10-10) escapes the parsed email address withhtmlspecialchars(..., ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8'), which does not escape double-quote characters, and then interpolates it into a double-quoted HTML href attribute:The email autolink regex in
parseLt()(/^<([^\s>]*?@[^\s]*?\.\w+?)>/) allows"in the local part. Input<"onmouseover=alert(1)//@x.y>is parsed as an email autolink and rendered as:Verified with html5lib (faithful HTML5 tokenizer): the browser parses this as
<a href="mailto:" onmouseover='alert(1)//@x.y"'>— a liveonmouseoverevent handler. On hover,alert(1)executes.Why this is distinct from CVE-2018-1000874
That CVE (DISPUTED) was about fenced-code-block raw HTML passthrough. This bug is not raw HTML passthrough:
parseLt()routes<...@x.y>torenderEmail()before the raw-HTML fallback (parseInlineHtml). The broken HTML is generated by the library from a markdown-syntax autolink, not passed through from user HTML. I acknowledge the maintainer's documented position that output should be filtered with HTML Purifier; this is offered as an escaping defect the library itself introduces.Affected
Markdown,MarkdownExtra,GithubMarkdown(sharedLinkTrait)2b2461b)CVSS v3.1
5.8 Medium —
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:NConstraint: the injected portion cannot contain whitespace (regex excludes
\s), so the practical payload is interaction-required (onmouseover); no no-interaction payload found.Suggested fix
Reproduction
Output:
Independent discovery during a security audit. Verified novel: OSV empty, GitHub Advisory DB empty, no prior issue/comment mentions
renderEmail/mailto/ENT_NOQUOTES.