mirror of
https://github.com/rr-/szurubooru.git
synced 2025-07-17 08:26:24 +00:00
client/markdown: prevent arbitrary tags
Introduced in 0137cf383a
, anywhere that
allows markdown e.g. comments allowed any arbitrary tag that wasn't
explicitly banned by DOMPurify, since it cannot know whether it came
from our Markdown renderer or from the user.
People could add arbitrary <style> tags that mess with the page,
<button>s etc. It did not lead to XSS since DOMPurify strips it,
but still unacceptable.
escapeHtml is identical to the old behavior of marked.js sanitize=true
This commit is contained in:
@ -110,24 +110,22 @@ class StrikeThroughWrapper extends BaseMarkdownWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
function createRenderer() {
|
||||
function sanitize(str) {
|
||||
return str.replace(/&<"/g, (m) => {
|
||||
if (m === "&") {
|
||||
return "&";
|
||||
}
|
||||
if (m === "<") {
|
||||
return "<";
|
||||
}
|
||||
return """;
|
||||
});
|
||||
}
|
||||
function escapeHtml(unsafe) {
|
||||
return unsafe
|
||||
.toString()
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function createRenderer() {
|
||||
const renderer = new marked.Renderer();
|
||||
renderer.image = (href, title, alt) => {
|
||||
let [_, url, width, height] =
|
||||
/^(.+?)(?:\s=\s*(\d*)\s*x\s*(\d*)\s*)?$/.exec(href);
|
||||
let res = '<img src="' + sanitize(url) + '" alt="' + sanitize(alt);
|
||||
let res = '<img src="' + escapeHtml(url) + '" alt="' + escapeHtml(alt);
|
||||
if (width) {
|
||||
res += '" width="' + width;
|
||||
}
|
||||
@ -156,6 +154,7 @@ function formatMarkdown(text) {
|
||||
new SmallWrapper(),
|
||||
new StrikeThroughWrapper(),
|
||||
];
|
||||
text = escapeHtml(text);
|
||||
for (let wrapper of wrappers) {
|
||||
text = wrapper.preprocess(text);
|
||||
}
|
||||
@ -182,6 +181,7 @@ function formatInlineMarkdown(text) {
|
||||
new SmallWrapper(),
|
||||
new StrikeThroughWrapper(),
|
||||
];
|
||||
text = escapeHtml(text);
|
||||
for (let wrapper of wrappers) {
|
||||
text = wrapper.preprocess(text);
|
||||
}
|
||||
@ -196,4 +196,5 @@ function formatInlineMarkdown(text) {
|
||||
module.exports = {
|
||||
formatMarkdown: formatMarkdown,
|
||||
formatInlineMarkdown: formatInlineMarkdown,
|
||||
escapeHtml: escapeHtml,
|
||||
};
|
||||
|
@ -156,16 +156,6 @@ function makeCssName(text, suffix) {
|
||||
return suffix + "-" + text.replace(/[^a-z0-9]/g, "_");
|
||||
}
|
||||
|
||||
function escapeHtml(unsafe) {
|
||||
return unsafe
|
||||
.toString()
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function arraysDiffer(source1, source2, orderImportant) {
|
||||
source1 = [...source1];
|
||||
source2 = [...source2];
|
||||
@ -221,7 +211,7 @@ module.exports = {
|
||||
enableExitConfirmation: enableExitConfirmation,
|
||||
disableExitConfirmation: disableExitConfirmation,
|
||||
confirmPageExit: confirmPageExit,
|
||||
escapeHtml: escapeHtml,
|
||||
escapeHtml: markdown.escapeHtml,
|
||||
makeCssName: makeCssName,
|
||||
splitByWhitespace: splitByWhitespace,
|
||||
arraysDiffer: arraysDiffer,
|
||||
|
Reference in New Issue
Block a user