Одно из возможных исправлений в wmd.js, в методе pushPreviewHtml()
. Вот оригинальный код из версии WMD с переполнением стека на GitHub :
if (wmd.panels.preview) {
wmd.panels.preview.innerHTML = text;
}
Вы можете заменить его некоторым кодом очистки. Вот адаптация кода, который переполнение стека использует в ответ на этот пост , который ограничивается белым списком тегов, а для элементов IMG и A ограничивается белым списком атрибутов (и в определенном порядке тоже !). См. Сообщение Meta Stack Overflow Какие теги HTML разрешены для переполнения стека, сбоя сервера и суперпользователя? для получения дополнительной информации о белом списке.
Примечание: этот код, безусловно, можно улучшить, например, разрешить атрибуты из белого списка в любом порядке. Он также запрещает использование mailto: URL-адресов, что, вероятно, полезно на интернет-сайтах, но на вашем собственном интранет-сайте это может быть не лучшим подходом.
if (wmd.panels.preview) {
// Original WMD code allowed JavaScript injection, like this:
// <img src="http://www.google.com/intl/en_ALL/images/srpr/logo1w.png" onload="alert('haha');"/>
// Now, we first ensure elements (and attributes of IMG and A elements) are in a whitelist,
// and if not in whitelist, replace with blanks in preview to prevent XSS attacks
// when editing malicious Markdown.
var okTags = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i;
var okLinks = /^(<a\shref="(\#\d+|(https?|ftp):\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+)"(\stitle="[^"<>]+")?\s?>|<\/a>)$/i;
var okImg = /^(<img\ssrc="https?:(\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+)"(\swidth="\d{1,3}")?(\sheight="\d{1,3}")?(\salt="[^"<>]*")?(\stitle="[^"<>]*")?\s?\/?>)$/i;
text = text.replace(/<[^<>]*>?/gi, function (tag) {
return (tag.match(okTags) || tag.match(okLinks) || tag.match(okImg)) ? tag : ""
})
wmd.panels.preview.innerHTML = text; // Original code
}
Также обратите внимание, что это исправление отсутствует в версии Переполнение стека WMD на GitHub - очевидно, что изменение было внесено позже и не возвращено в GitHub.
ОБНОВЛЕНИЕ: чтобы не нарушать функцию автоматического создания гиперссылок при вводе URL-адреса, вам также необходимо внести изменения в showdown.js, как показано ниже:
Оригинальный код:
var _DoAutoLinks = function(text) {
text = text.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"<a href=\"$1\">$1</a>");
// Email addresses: <address@domain.foo>
/*
text = text.replace(/
<
(?:mailto:)?
(
[-.\w]+
\@
[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
)
>
/gi, _DoAutoLinks_callback());
*/
text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
function(wholeMatch,m1) {
return _EncodeEmailAddress( _UnescapeSpecialChars(m1) );
}
);
return text;
}
Фиксированный код:
var _DoAutoLinks = function(text) {
// use simplified format for links, to enable whitelisting link attributes
text = text.replace(/(^|\s)(https?|ftp)(:\/\/[-A-Z0-9+&@#\/%?=~_|\[\]\(\)!:,\.;]*[-A-Z0-9+&@#\/%=~_|\[\]])($|\W)/gi, "$1<$2$3>$4");
text = text.replace(/<((https?|ftp):[^'">\s]+)>/gi, '<a href="$1">$1</a>');
return text;
}