Очистите уценку от XSS
Я использую Markdown для предоставления простого способа написания сообщений моим пользователям в моем сценарии форума.
Я пытаюсь очистить все пользовательские входные данные, но у меня проблема с входными данными Markdown.
Мне нужно сохранить в базе данных текст уценки, а не версию, преобразованную в HTML, потому что пользователям разрешено редактировать свои сообщения.
В принципе, мне нужно что-то вроде того, что делает StackOverflow.
Я прочитал эту статью об уязвимости XSS в Markdown. И единственное решение Я обнаружил, что нужно использовать HTML_purifier перед каждым выводом, который предоставляет мой скрипт.
Я думаю, что это может замедлить мой скрипт, я представляю вывод 20 сообщений и запуск HTML_purifier для каждого из них...
Итак, я пытался найти решение для очистки от уязвимостей XSS, очищающих входные данные вместо выходных.
Я не могу запустить HTML_purifier на входе, потому что мой текст - это уценка, а не HTML. И если я конвертирую его для получения HTML, я не смогу конвертировать обратно для превращения в уценку.
Я уже удалите (я надеюсь) весь HTML-код с помощью:
htmlspecialchars(strip_tags($text));
Я подумал о другом решении:
Когда пользователь пытается отправить новое сообщение: Преобразуйте входные данные из Markdown в HTML, запустите HTML_purifier, и если он обнаружит какую-либо инъекцию XSS, он просто вернет ошибку. Но я не знаю, как это сделать, и не знаю, позволяет ли это HTML_purifier.
Я нашел там много вопросов об одной и той же проблеме, но все решения заключались в том, чтобы сохранить входные данные в виде HTML. Мне нужно хранить как Уценка.
У кого-нибудь есть какие-нибудь советы?
3 answers
- Запустите уценку на входе
- Запустите очиститель HTML для HTML, сгенерированного Markdown. Настройте его так, чтобы он разрешал ссылки, атрибуты href и т. Д. (Он все равно должен удалять команды
javascript:
)
// the nasty stuff :)
$content = "> hello <a name=\"n\" \n href=\"javascript:alert('xss')\">*you*</a>";
require '/path/to/markdown.php';
// at this point, the generated HTML is vulnerable to XSS
$content = Markdown($content);
require '/path/to//HTMLPurifier/HTMLPurifier.auto.php';
$config = HTMLPurifier_Config::createDefault();
$config->set('Core.Encoding', 'UTF-8');
$config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
$config->set('Cache.DefinitionImpl', null);
// put here every tag and attribute that you want to pass through
$config->set('HTML.Allowed', 'a[href|title],blockquote[cite]');
$purifier = new HTMLPurifier($config);
// here, the javascript command is stripped off
$content = $purifier->purify($content);
print $content;
Решено...
$text = "> hello <a name=\"n\"
> href=\"javascript:alert('xss')\">*you*</a>";
$text = strip_tags($text);
$text = Markdown($text);
echo $text;
Он возвращает:
<blockquote>
<p>hello href="javascript:alert('xss')"><em>you</em></p>
</blockquote>
И не:
<blockquote>
<p>hello <a name="n" href="javascript:alert('xss')"><em>you</em></a></p>
</blockquote>
Похоже, что strip_tags()
это работает.
Объединено с:
$text = preg_replace('/href=(\"|)javascript:/', "", $text);
Весь ввод должен быть очищен от инъекций XSS. Поправьте меня, если я ошибаюсь.
Вывод html-кода вашей уценки зависит только от синтаксического анализатора md, поэтому вы можете
-
Преобразуйте свой md в html и очистите html после этого, как описано здесь:
Избавление от уязвимости XSS с сохранением синтаксиса уценки?
- или вы можете изменить свой синтаксический анализатор md, чтобы проверять каждый параметр, который переходит в атрибут html, на наличие признаков xss. Ofc вы должны избегать html-тегов перед синтаксическим анализом. Я думаю, что это решение намного быстрее, чем другое, потому что по простым текстам вы обычно должны проверять только URL-адреса по изображениям и ссылкам.