fix security 1
This commit is contained in:
+14
-6
@@ -5,9 +5,17 @@ function escapeHtml(value) {
|
||||
}
|
||||
|
||||
function safeUrl(value) {
|
||||
const url = String(value).trim();
|
||||
if (/^(https?:\/\/|mailto:|\/|\.\/|\.\.\/|#)/i.test(url)) return escapeHtml(url);
|
||||
return "#";
|
||||
const raw = String(value || "").trim();
|
||||
if (!raw || raw.startsWith("//")) return "#";
|
||||
if (raw.startsWith("#")) return escapeHtml(raw);
|
||||
try {
|
||||
const url = new URL(raw, location.origin);
|
||||
if (url.protocol === "mailto:") return escapeHtml(url.href);
|
||||
if (url.protocol !== "http:" && url.protocol !== "https:") return "#";
|
||||
return escapeHtml(url.href);
|
||||
} catch {
|
||||
return "#";
|
||||
}
|
||||
}
|
||||
|
||||
const emoji = EMOJI_SHORTCODES;
|
||||
@@ -24,11 +32,11 @@ function inline(value) {
|
||||
html = html.replace(/`([^`]+)`/g, (_, code) => stash(`<code>${code}</code>`));
|
||||
html = html.replace(/!\[([^\]]*)\]\(([^\s)]+)(?:\s+["']([^"']*)["'])?\)/g, (_, alt, url, title) => {
|
||||
const titleAttr = title ? ` title="${escapeHtml(title)}"` : "";
|
||||
return stash(`<img src="${safeUrl(url)}" alt="${alt}" loading="lazy" decoding="async" draggable="false" contenteditable="false"${titleAttr}>`);
|
||||
return stash(`<img src="${safeUrl(url)}" alt="${alt}" loading="lazy" decoding="async" referrerpolicy="no-referrer" draggable="false" contenteditable="false"${titleAttr}>`);
|
||||
});
|
||||
html = html.replace(/\[([^\]]+)\]\(([^\s)]+)(?:\s+["']([^"']*)["'])?\)/g, (_, label, url, title) => {
|
||||
const titleAttr = title ? ` title="${escapeHtml(title)}"` : "";
|
||||
return stash(`<a href="${safeUrl(url)}" target="_blank" rel="noopener noreferrer"${titleAttr}>${label}</a>`);
|
||||
return stash(`<a href="${safeUrl(url)}" target="_blank" rel="noopener noreferrer" referrerpolicy="no-referrer"${titleAttr}>${label}</a>`);
|
||||
});
|
||||
html = html.replace(/\[\^([^\]\s]+)\]/g, (_, id) => stash(`<sup class="footnote-ref"><a href="#fn-${escapeHtml(id)}" id="fnref-${escapeHtml(id)}">?</a></sup>`));
|
||||
|
||||
@@ -44,7 +52,7 @@ function inline(value) {
|
||||
html = html.replace(/(^|[\s(])((?:https?:\/\/|mailto:)[^\s<]+)/gi, (match, prefix, url) => {
|
||||
const clean = url.replace(/[.,!?;:]+$/, "");
|
||||
const suffix = url.slice(clean.length);
|
||||
return `${prefix}${stash(`<a href="${safeUrl(clean)}" target="_blank" rel="noopener noreferrer">${clean}</a>`)}${suffix}`;
|
||||
return `${prefix}${stash(`<a href="${safeUrl(clean)}" target="_blank" rel="noopener noreferrer" referrerpolicy="no-referrer">${clean}</a>`)}${suffix}`;
|
||||
});
|
||||
|
||||
return html.replace(/\u0000T(\d+)\u0000/g, (_, index) => tokens[Number(index)] || "");
|
||||
|
||||
Reference in New Issue
Block a user