При получении пользовательского ввода в формах я хочу определить, не содержат ли такие поля, как «имя пользователя» или «адрес» разметку, имеющую особое значение в XML (RSS-каналы) или (X) HTML (при отображении ).
Итак, какой из них является правильным способом определить, не содержит ли введенный ввод каких-либо специальных символов в контексте HTML и XML?
if (mb_strpos($data, '<') === FALSE AND mb_strpos($data, '>') === FALSE)
или
if (htmlspecialchars($data, ENT_NOQUOTES, 'UTF-8') === $data)
или
if (preg_match("/[^\p{L}\-.']/u", $text)) // problem: also caches symbols
Пропустил ли я что-нибудь еще, например последовательности байтов или другие хитрые способы получить теги разметки вокруг таких вещей, как "javascript:"? Насколько мне известно, все атаки XSS и CSFR требуют или
>
вокруг значений, чтобы браузер выполнил код (ну, по крайней мере, в любом случае из Internet Explorer 6 или более поздней версии) - это правильно?
Я не ищу чего-либо, что можно было бы уменьшить или отфильтровать вводимые данные. Я просто хочу найти опасные последовательности символов при использовании в контексте XML или HTML. ( strip_tags ()
ужасно небезопасно. Как сказано в руководстве, оно не проверяет наличие искаженного HTML.)
Я думаю, мне нужно уточнить, что людей много ошибочно принимают этот вопрос за вопрос о базовой безопасности посредством «экранирования» или «фильтрации» опасных символов. Это не тот вопрос, и большинство приведенных простых ответов в любом случае не решат эту проблему.
if (mb_strpos ($ data, '') === FALSE)
Теперь, когда данные находятся в моем приложении, я делаю с ними две вещи: 1) отображаю в формате, подобном HTML, или 2) отображаю внутри элемента формата для редактирования.
Первый безопасен в контексте XML и HTML
Php print $ input; ?>
'
Вторая форма более опасна, но все же должна быть безопасной:
Вы можете загрузить созданную мной суть и запустить код в виде текста или ответа HTML, чтобы увидеть, о чем я говорю. Эта простая проверка проходит через http://ha.ckers.org Шпаргалку по XSS , но я не могу найти ничего, что помогло бы ей. (Я игнорирую Internet Explorer 6 и ниже).
Я назначил еще одну награду, чтобы наградить кого-то, кто может показать проблему с этим подходом или слабость в его реализации.
Мы хотим защитить DOM - так почему бы просто не спросить об этом? Ответ Тимура приводит к следующему:
function not_markup($string)
{
libxml_use_internal_errors(true);
if ($xml = simplexml_load_string("$string "))
{
return $xml->children()->count() === 0;
}
}
if (not_markup($_POST['title'])) ...