Harden rendered markdown links

This commit is contained in:
Rūdolfs Ošiņš
2026-05-28 16:16:41 +02:00
parent 747d9b05f9
commit 17cd7adcb8
2 changed files with 11 additions and 5 deletions
+1
View File
@@ -129,6 +129,7 @@
const url = new URL(e.href); const url = new URL(e.href);
if (url.origin !== window.origin) { if (url.origin !== window.origin) {
e.target = "_blank"; e.target = "_blank";
e.rel = "noopener noreferrer";
} }
} catch (e) { } catch (e) {
console.warn("Not able to parse url", e); console.warn("Not able to parse url", e);
+10 -5
View File
@@ -2,6 +2,7 @@ import type { Config } from "dompurify";
import type { MarkedExtension, Tokens } from "marked"; import type { MarkedExtension, Tokens } from "marked";
import type { Route } from "@app/lib/router"; import type { Route } from "@app/lib/router";
import escape from "lodash/escape";
import footnoteMarkedExtension from "marked-footnote"; import footnoteMarkedExtension from "marked-footnote";
import katexMarkedExtension from "marked-katex-extension"; import katexMarkedExtension from "marked-katex-extension";
import linkifyMarkedExtension from "marked-linkify-it"; import linkifyMarkedExtension from "marked-linkify-it";
@@ -29,6 +30,7 @@ export const sanitizeConfig: Config = {
"href", "href",
"id", "id",
"name", "name",
"rel",
"src", "src",
"target", "target",
"text", "text",
@@ -106,10 +108,8 @@ export class Renderer extends BaseRenderer {
const text = this.parser.parseInline(tokens); const text = this.parser.parseInline(tokens);
if (href.startsWith("#")) { if (href.startsWith("#")) {
// By lowercasing we avoid casing mismatches, between headings and links. // By lowercasing we avoid casing mismatches, between headings and links.
return `<a ${title ? `title="${title}"` : ""} href="${href.toLowerCase()}">${text}</a>`; href = href.toLowerCase();
} } else if (this.#route.resource === "repo.source" && !isUrl(href)) {
if (this.#route.resource === "repo.source" && !isUrl(href)) {
href = routeToPath({ href = routeToPath({
...this.#route, ...this.#route,
path: canonicalize(href, this.#route.path || "README.md"), path: canonicalize(href, this.#route.path || "README.md"),
@@ -117,7 +117,12 @@ export class Renderer extends BaseRenderer {
}); });
} }
return `<a ${title ? `title="${title}"` : ""} href="${href}">${text}</a>`; const attrs = [`href="${escape(href)}"`];
if (title) {
attrs.push(`title="${escape(title)}"`);
}
return `<a ${attrs.join(" ")}>${text}</a>`;
} }
} }