diff --git a/src/markdown.test.ts b/src/markdown.test.ts index d7a3742..fc4b513 100644 --- a/src/markdown.test.ts +++ b/src/markdown.test.ts @@ -57,6 +57,19 @@ test("safe Markdown mode keeps HTML examples inert inside code fences", async () assert.match(html, /
{
+ const html = await renderMarkdown(
+ "[*An Economy of AI Agents*](https://example.com/economy) [**blocked label**](javascript:alert(1))",
+ { allowRawHtml: false },
+ );
+
+ assert.equal(
+ html,
+ 'An Economy of AI Agents blocked label
\n',
+ );
+ assert.doesNotMatch(html, /\*An Economy|javascript:/);
+});
+
test("safe Markdown mode denies executable link and image protocols", async () => {
const html = await renderMarkdown(
"[run](javascript:alert(1)) [encoded](javascript:alert(1))  [slash](\\\\evil.example/path) [encoded-slash](\\evil.example/path)  [source](https://example.com/) [local](/knowledge/example)",
diff --git a/src/markdown.ts b/src/markdown.ts
index 1a271bd..eadf882 100644
--- a/src/markdown.ts
+++ b/src/markdown.ts
@@ -78,9 +78,9 @@ export async function renderMarkdown(
return allowRawHtml ? text : escapeHtml(text);
},
...(!allowRawHtml ? {
- link({ href, title, text }) {
+ link({ href, title, tokens }) {
const safeHref = safeMarkdownUrl(href, true);
- const label = escapeHtml(text);
+ const label = this.parser.parseInline(tokens);
if (!safeHref) return label;
const titleAttribute = title ? ` title="${escapeHtml(title)}"` : "";
return `${label}`;