очистка данных перед внедрением mysql и xss - правильно ли я делаю это с pdo и htmlpurifier

Я все еще работаю над защитой своего веб-приложения. Я решил использовать библиотеку PDO для предотвращения внедрения mysql и очиститель html для предотвращения атак xss. Поскольку все данные, поступающие с ввода, поступают в базу данных, для работы с данными я выполняю такие действия:

  1. получить данные из поля ввода
  2. запустить pdo, подготовить запрос
  3. привязать каждую переменную (переменную POST) к запросу, очистив ее с помощью очистителя html
  4. выполнить запрос (сохранить в базу данных).

В коде это выглядит так:

// start htmlpurifier
require_once '/path/to/htmlpurifier/library/HTMLPurifier.auto.php';

$config = HTMLPurifier_Config::createDefault();
$purifier = new HTMLPurifier($config);

// start pdo
$pdo = new PDO('mysql:host=host;dbname=dbname', 'login', 'pass');
$pdo -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// prepare and bind
$stmt = $pdo -> prepare('INSERT INTO `table` (`field1`) VALUES ( :field1 )');
// purify data and bind it.
$stmt -> bindValue(':field1',   $purifier->purify($_POST['field1']), PDO::PARAM_INT); 
// execute (save to database)
$stmt -> execute();

Вот вопросы:

  1. Это все, что мне нужно сделать, чтобы предотвратить внедрение XSS и mysql? Я знаю, что не могу быть уверен на 100%, но в большинстве случаев должно ли это работать нормально и достаточно ли этого?

  2. Должен ли я снова дезинфицировать данные при захвате их из базы данных и размещении в браузере или фильтрации перед сохранением?

  3. Я читал в вики, что разумно включить magic_quotes. Ofocurse, если магические кавычки помещают ненужные косые черты, это может раздражать, но если я не забочусь об этих косых чертах, не превращает ли это просто в потерю еще одной линии защиты?

Ответ:

Обратите внимание, что код, который я написал в этом примере, является просто примером. Существует много входных данных, и запрос к БД намного сложнее. К сожалению, я не могу согласиться с вами в том, что если переменная типа PDO должна быть int, мне не нужно фильтровать ее с помощью XSS-атак. Поправьте меня, если я ошибаюсь:

Если ввод должен быть целым числом, и это так, то все в порядке - я могу поместить его в БД. Но помните, что любой ввод можно изменить и стоит ожидать худшего. Итак, если все в порядке, то все в порядке, но если злоумышленник введет XSS-код, у меня будет несколько линий защиты:

  1. защита на стороне клиента - проверьте, является ли это числовым значением. Легко пойти на компромисс, но может остановить новичков.
  2. на стороне сервера - тест внедрения xss (с очисткой html или т.е. htmlspecialchars)
  3. сторона db - если кто-то каким-то образом поместит вредоносный код, который позволит избежать защиты xss, база данных вернет ошибку, потому что должно быть целое число, а не какая-либо другая переменная.

Я думаю, что это не делает ничего плохого, и это может сделать много хорошего. Конечно, мы теряем некоторое время, чтобы все просчитать, но я думаю, мы должны взвесить производительность и безопасность и определить, что для вас важнее. Мое приложение будет использоваться 2-3 пользователями одновременно. Не много. И безопасность для меня гораздо важнее, чем производительность.

К счастью, весь мой сайт в кодировке UTF8, так что проблем с кодировкой я не ожидаю.

При поиске в сети я встретил много мнений о addlashes(), stripslashes(), htmlspecialchars(), htmlentities().. и я выбрал htmlpurity и pdo. Все говорят, что это лучшее решение перед угрозами внедрения xss и mysql. Если у вас есть другое мнение, поделитесь.


person Kalreg    schedule 01.04.2012    source источник


Ответы (1)


  1. Что касается SQL-инъекций, да, вы можете быть уверены на 100%, если всегда используете подготовленные операторы. Что касается XSS, вы также должны убедиться, что все ваши страницы имеют кодировку UTF-8. HTML Purifier очищает данные, предполагая, что они закодированы в UTF-8, поэтому могут возникнуть непредвиденные проблемы, если вы поместите эти данные на страницу с другой кодировкой. Каждая страница должна иметь тег <meta>, указывающий кодировку UTF-8.

  2. Нет, вам не нужно дезинфицировать данные после того, как вы извлекаете их из БД, при условии, что вы уже дезинфицировали их и не добавляете к ним какие-либо данные, отправленные пользователями.

  3. Если вы всегда используете подготовленные операторы, волшебные кавычки будут не более чем неприятностью. Он не предоставляет никаких дополнительных линий защиты, потому что подготовленные операторы пуленепробиваемы.

А теперь вопрос к вам. PDO::PARAM_INT превратит $field1 в целое число. Целое число нельзя использовать в атаке с внедрением SQL. Почему вы пропускаете его через HTML Purifier, если это просто целое число?

HTML Purifier все замедляет, поэтому его следует использовать только в тех полях, где вы хотите разрешить HTML. Если это целое число, просто выполните intval($var), чтобы уничтожить все, что не является числом. Если это строка, которая в любом случае не должна содержать HTML, просто выполните htmlspecialchars($var, ENT_COMPAT, 'UTF-8'), чтобы уничтожить весь HTML. Оба они гораздо более эффективны и одинаково безопасны, если вам не нужно разрешать HTML. Каждое поле должно быть очищено, но каждое поле должно быть очищено в соответствии с тем, что оно должно содержать.

Ответ на ваши дополнения:

Я не имел в виду, что если переменная должна содержать целое число, то ее не нужно очищать. Извините, если мой комментарий показался вам таким. Я пытался сказать, что если переменная должна содержать целое число, ее не следует очищать с помощью HTML Purifier. Вместо этого ее следует проверять/очищать с помощью другой функции, например intval() или ctype_digit(). . HTML Purifier в этом случае не только будет использовать ненужные ресурсы, но и не может гарантировать, что после этого переменная будет содержать целое число. intval() гарантирует, что результатом будет целое число, и результат в равной степени безопасен, потому что никто не может использовать целое число для проведения атаки XSS или внедрения SQL.

Точно так же, если переменная не должна содержать какой-либо HTML, например заголовок вопроса, вы должны использовать htmlspecialchars() или htmlentities(). Очиститель HTML следует использовать только в том случае, если вы хотите, чтобы ваши пользователи вводили HTML (например, с помощью редактора WYSIWYG). Поэтому я не хотел сказать, что некоторые виды входных данных не нуждаются в санации. Я считаю, что входные данные следует очищать с помощью различных функций в зависимости от того, что вы хотите, чтобы они содержали. Не существует единого решения, которое работает на всех типах входных данных. Вполне возможно написать безопасный веб-сайт без использования HTML Purifier, если вы когда-либо принимаете только текстовые комментарии.

«Защита на стороне клиента» — это не линия защиты, это просто удобство.

У меня также возникает неприятное ощущение, что вы смешиваете XSS и SQL-инъекцию вместе, когда они представляют собой совершенно разные векторы атаки. "инъекция XSS"? Что это?

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

person kijin    schedule 01.04.2012
comment
у вас есть ответ в моем предыдущем посте. - person Kalreg; 01.04.2012