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 escapeHtml(unsafe) {
|
||||||
function sanitize(str) {
|
return unsafe
|
||||||
return str.replace(/&<"/g, (m) => {
|
.toString()
|
||||||
if (m === "&") {
|
.replace(/&/g, "&")
|
||||||
return "&";
|
.replace(/</g, "<")
|
||||||
}
|
.replace(/>/g, ">")
|
||||||
if (m === "<") {
|
.replace(/"/g, """)
|
||||||
return "<";
|
.replace(/'/g, "'");
|
||||||
}
|
}
|
||||||
return """;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
function createRenderer() {
|
||||||
const renderer = new marked.Renderer();
|
const renderer = new marked.Renderer();
|
||||||
renderer.image = (href, title, alt) => {
|
renderer.image = (href, title, alt) => {
|
||||||
let [_, url, width, height] =
|
let [_, url, width, height] =
|
||||||
/^(.+?)(?:\s=\s*(\d*)\s*x\s*(\d*)\s*)?$/.exec(href);
|
/^(.+?)(?:\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) {
|
if (width) {
|
||||||
res += '" width="' + width;
|
res += '" width="' + width;
|
||||||
}
|
}
|
||||||
@ -156,6 +154,7 @@ function formatMarkdown(text) {
|
|||||||
new SmallWrapper(),
|
new SmallWrapper(),
|
||||||
new StrikeThroughWrapper(),
|
new StrikeThroughWrapper(),
|
||||||
];
|
];
|
||||||
|
text = escapeHtml(text);
|
||||||
for (let wrapper of wrappers) {
|
for (let wrapper of wrappers) {
|
||||||
text = wrapper.preprocess(text);
|
text = wrapper.preprocess(text);
|
||||||
}
|
}
|
||||||
@ -182,6 +181,7 @@ function formatInlineMarkdown(text) {
|
|||||||
new SmallWrapper(),
|
new SmallWrapper(),
|
||||||
new StrikeThroughWrapper(),
|
new StrikeThroughWrapper(),
|
||||||
];
|
];
|
||||||
|
text = escapeHtml(text);
|
||||||
for (let wrapper of wrappers) {
|
for (let wrapper of wrappers) {
|
||||||
text = wrapper.preprocess(text);
|
text = wrapper.preprocess(text);
|
||||||
}
|
}
|
||||||
@ -196,4 +196,5 @@ function formatInlineMarkdown(text) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
formatMarkdown: formatMarkdown,
|
formatMarkdown: formatMarkdown,
|
||||||
formatInlineMarkdown: formatInlineMarkdown,
|
formatInlineMarkdown: formatInlineMarkdown,
|
||||||
|
escapeHtml: escapeHtml,
|
||||||
};
|
};
|
||||||
|
@ -156,16 +156,6 @@ function makeCssName(text, suffix) {
|
|||||||
return suffix + "-" + text.replace(/[^a-z0-9]/g, "_");
|
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) {
|
function arraysDiffer(source1, source2, orderImportant) {
|
||||||
source1 = [...source1];
|
source1 = [...source1];
|
||||||
source2 = [...source2];
|
source2 = [...source2];
|
||||||
@ -221,7 +211,7 @@ module.exports = {
|
|||||||
enableExitConfirmation: enableExitConfirmation,
|
enableExitConfirmation: enableExitConfirmation,
|
||||||
disableExitConfirmation: disableExitConfirmation,
|
disableExitConfirmation: disableExitConfirmation,
|
||||||
confirmPageExit: confirmPageExit,
|
confirmPageExit: confirmPageExit,
|
||||||
escapeHtml: escapeHtml,
|
escapeHtml: markdown.escapeHtml,
|
||||||
makeCssName: makeCssName,
|
makeCssName: makeCssName,
|
||||||
splitByWhitespace: splitByWhitespace,
|
splitByWhitespace: splitByWhitespace,
|
||||||
arraysDiffer: arraysDiffer,
|
arraysDiffer: arraysDiffer,
|
||||||
|
Reference in New Issue
Block a user