Эффективно дезинфицировать введенный пользователем текст

У меня есть html-форма, которая принимает введенный пользователем текст размером около 1000 и отправляется на php-страницу, где будет храниться в базе данных mysql. Я использую PDO с подготовленными инструкциями для предотвращения внедрения sql. Но для дезинфекции текста, введенного пользователем, какие меры необходимо предпринять?

Я хочу предотвратить любую инъекцию скрипта, xss-атаки и т. Д.

Безопасность – интересная концепция и привлекает к ней много людей. К сожалению, это сложный вопрос, и даже профессионалы ошибаются. Я нашел дыры в безопасности в Google (CSRF), Facebook (больше CSRF), нескольких крупных интернет-магазинах (в основном, SQL injection / XSS), а также тысячи небольших сайтов как корпоративных, так и личных.

Это мои рекомендации:

1) Использовать параметризованные запросы
Параметрированные запросы заставляют значения, переданные запросу, обрабатываться как отдельные данные, поэтому входные значения не могут быть проанализированы СУБД SQL-кодом. Многие люди будут рекомендовать вам избегать строк, используя mysql_real_escape_string() , но, вопреки распространенному мнению, это не mysql_real_escape_string() решение SQL-инъекции. Возьмите этот запрос, например:

 SELECT * FROM users WHERE userID = $_GET['userid'] 

Если $_GET['userid'] установлен в 1 OR 1=1 , специальных символов не будет, и он не будет отфильтрован. Это приводит к возврату всех строк. Или, что еще хуже, что, если он установлен в 1 OR is_admin = 1 ?

Параметрированные запросы предотвращают появление такого рода инъекций.

2) Подтвердите свои входы
Запросы с параметризованными запросами велики, но иногда неожиданные значения могут вызвать проблемы с вашим кодом. Убедитесь, что вы проверяете, что они находятся в пределах диапазона, и что они не позволят текущему пользователю изменять то, что они не могут.

Например, у вас может быть форма смены пароля, которая отправляет запрос POST скрипту, который изменяет свой пароль. Если вы поместите свой идентификатор пользователя в скрытую переменную в форме, они могут изменить его. Отправка id=123 вместо id=321 может означать, что они меняют чужой пароль. Убедитесь, что все верно проверено с точки зрения типа, диапазона и доступа.

3) Используйте htmlspecialchars для выхода из отображаемого пользовательского ввода
Скажем, ваш пользователь вводит их «обо мне», как-то вроде этого:
</div><script>document.alert('hello!');</script><div>
Проблема заключается в том, что ваш вывод будет содержать разметку, введенную пользователем. Попытка фильтровать это с помощью черных списков – это просто плохая идея. Используйте htmlspecialchars для фильтрации строк, чтобы HTML-теги были преобразованы в объекты HTML.

4) Не используйте $ _REQUEST
Атаки с перекрестными запросами (CSRF) работают, заставляя пользователя щелкнуть ссылку или посетить URL-адрес, представляющий скрипт, который выполняет действие на сайте, для которого они вошли. Переменная $_REQUEST представляет собой комбинацию $_GET , $_POST и $_COOKIE , что означает, что вы не можете определить разницу между переменной, которая была отправлена ​​в запросе POST (т. $_COOKIE Через тег input в вашей форме) или переменной, которая была установлена ​​в вашем URL как часть GET (например, page.php?id=1 ).

Предположим, пользователь хочет отправить кому-то личное сообщение. Они могут отправить запрос POST на sendmessage.php , с помощью, subject и message качестве параметров. Теперь давайте представим, что кто-то отправляет запрос GET:

 sendmessage.php?to=someone&subject=SPAM&message=VIAGRA! 

Если вы используете $_POST , вы не увидите ни одного из этих параметров, поскольку они установлены вместо $_GET . Ваш код не будет видеть $_POST['to'] или любую другую переменную, поэтому он не отправит сообщение. Однако, если вы используете $_REQUEST , $_GET и $_POST застревают вместе, поэтому злоумышленник может установить эти параметры как часть URL-адреса. Когда пользователь посещает этот URL-адрес, они непреднамеренно отправляют сообщение. Очень тревожная часть заключается в том, что пользователю ничего не нужно делать. Если злоумышленник создает вредоносную страницу, он может содержать iframe , указывающий на URL. Пример:

 <iframe src="http://yoursite.com/sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!"> </iframe> 

Это приводит к тому, что пользователь отправляет сообщения людям, даже не осознавая, что они что-то сделали. По этой причине вам следует избегать $_REQUEST и вместо этого использовать $_POST и $_GET .

5) Относитесь ко всему, что вам дано как подозрительное (или даже злонамеренное)
Вы не представляете, что пользователь посылает вам. Это может быть законным. Это может быть атака. Никогда не доверяйте тому, что отправил вам пользователь. Преобразуйте в правильные типы, проверьте входные данные, используйте белые списки для фильтрации там, где это необходимо (избегайте черных списков). Это включает в себя все, что отправлено через $_GET , $_POST , $_COOKIE и $_FILES .

Если вы будете следовать этим рекомендациям, вы будете иметь разумную позицию с точки зрения безопасности.

Вам нужно различать два типа атак: SQL-инъекция и XSS. SQL-инъекции можно избежать, используя подготовленные операторы или функции кавычек вашей библиотеки БД. Вы используете функцию кавычек, прежде чем вставлять ее в базу данных.

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

Также см. Ответ на аналогичный вопрос.

Вам нужно сделать две простые вещи, чтобы быть в безопасности:

  • Используйте подготовленные заявления или правильно выполняйте данные.
  • При выводе в HTML всегда избегайте использования htmlspecialchars ().