Совместите предварительный просмотр HTML редактора WMD с проверкой HTML-сервера HTML (например, встроенный код JavaScript)

StackOverflow https://stackoverflow.com/questions/2837593

Вопрос

Есть много вопросов переполнения стека (например, Whitelisting, предотвращение XSS с помощью контроля WMD в C # а также WMD Markdown и Server-Side) О том, как выполнить Server Source Scrubbing of Markdown, создаваемого редактором WMD, чтобы убедиться, что генерируется HTML, не содержит вредоносного скрипта, как это:

<img onload="alert('haha');" 
   src="http://www.google.com/intl/en_ALL/images/srpr/logo1w.png" />

Но я не нашел хорошего способа подключить дыру на стороне клиента тоже. Валидация клиента не является заменой для очистки проверки на сервере, конечно, поскольку кто-либо может притворяться клиентом и разместить вас противную оценку. И если вы очищаете HTML на сервере, злоумышленник не может сохранить плохой HTML, поэтому никто другой не сможет увидеть его позже, и их файлы cookie украдены или сеансы угнались плохим сценарием. Таким образом, есть правильный случай, который может быть сделан, чтобы он не стоит соблюдать соблюдение правил без сценариев в панели предварительного просмотра WMD.

Но представьте, что злоумышленник нашел способ получить злоумышленную усадьбу на сервер (например, скомпрометированный корм на другой сайт, или содержимое, добавленное до фиксации ошибки XSS). Ваш серверный портрет, применимый при переводе усадки на HTML, обычно предотвратит, чтобы иметьщую плохую уценку отказаться пользователям. Но если злоумышленник может получить кого-то, чтобы отредактировать страницу (например, публикуя еще одну запись, заявив, что злонамеренная запись имела сломанную ссылку и просить кого-то его исправить), то кто-то, кто редактирует страницу, получает свои печенье. Это по общему признанию, угловой случай, но оно все равно стоит защищать.

Кроме того, это, вероятно, плохая идея, чтобы позволить окно предварительного просмотра клиента разрешить другое HTML, чем позволит ваш сервер.

Команда переполнения стека подключила это отверстие, внес изменения в WMD. Как они это делают?

Примечание. Я уже выяснил это, но требуется какой-то сложный JavaScript отладки, поэтому я отвечаю на мой вопрос здесь, чтобы помочь другим, кто может захотеть сделать такое же.

Это было полезно?

Решение

Одним из возможных исправлений находится в WMD.JS, в pushPreviewHtml() метод. Вот оригинальный код из Переполнение стека версия WMD на Github:

if (wmd.panels.preview) {
    wmd.panels.preview.innerHTML = text; 
}

Вы можете заменить его с помощью некоторого кода очистки. Вот адаптация кода, который использует переполнение стека В ответ на этот пост, который ограничивает белый список тегов, а для IMG и элементов ограничивает белью атрибутов (и в конкретном порядке!). Смотрите пост переполнения мета стека Какие HTML-теги разрешены на переполнении стека, неисправность сервера и Super User? Для получения дополнительной информации о беломте.

ПРИМЕЧАНИЕ. Этот код, безусловно, может быть улучшен, например, чтобы разрешить атрибуты WhiteListed в любом порядке. Он также отключает 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;
}

Другие советы

Это не проблема безопасности, чтобы позволить локальному пользователю выполнять скрипты в контексте страницы, если какая-либо сторона невозможно предоставить сценарию. Без редактора этого пользователь всегда может ввести javascript: URL-адрес на вашей странице или используйте Firebug или что-то подобное.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top