Фильтрация MySQL-запроса в PHP

Привет, я делаю некоторые запросы к базе данных MySQL, которая включает в себя некоторые пользовательские ввода. И мне было интересно, как предотвратить инъекционные атаки, например, если кто-то должен был вводить

"; a-MySQL query here;" 

Это будет выполнено, это позволит людям получить доступ к компрометации моей системы. Мне интересно, как я могу защитить от подобных вещей, возможно создать функцию, которая отфильтровывает запрос, ищущий плохие высказывания? или, возможно, не позволяя; персонаж?

Подводя итог:

  • Какова распространенная практика в настоящее время для предотвращения инъекционных атак?
  • Как мне это сделать?
  • Насколько эффективно это решение будет против людей, которые знают, что они делают, от изменения моей базы данных.

Единственный способ – правильно удалить данные, предоставленные пользователем. Другие указали на некоторые способы сделать это.

Есть и другой способ: подготовленные заявления и заполнители. Подготовленные утверждения поддерживаются каждым современным интерфейсом базы данных PHP, включая mysqli и PDO .

Давайте используем PDO в качестве демонстрации. Предположим, мы хотели обновить бит данных в таблице foo представленной пользователем.

 $sql = 'UPDATE foo SET bar = ? WHERE user_id = ?'; $sh = $db->prepare($sql); $sh->execute(array( $_POST['bar'], $_SESSION['user_id'] )); 

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

С другой стороны, вам все равно придется отфильтровывать их для неожиданного контента, такого как HTML, Javascript, письма, в которых вы ожидаете номера, и т. Д. Обеспечение безопасности данных для вставки в базу данных – это только половина битвы .

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

См. Подробнее: http://www.electrictoolbox.com/php-pdo-bound-placeholders/

Лучшим решением является запуск каждой части данных из дикой природы (пользователя) с помощью этой функции. PHP.net: MySQL Real Escape String. Это очистит большинство – если не все – проблемы с инъекцией, которые видны сегодня. Вам просто нужно сделать что-то вроде следующего:

 $var = mysql_real_escape_string($_GET['var']); $query = "INSERT INTO foo (var) VALUES (\"$var\"); 

Это всегда хорошая практика, чтобы заставить литье типов переменных, которые, как вы знаете, должны быть типом. Например, числовой идентификатор:

$id = (INT)$_GET['id'];

или

$id = ( is_numeric($_GET['id']) ? (INT)$_GET['id'] : -1; // replace -1 with FALSE, or NULL, etc

Который заставит эту переменную быть Целочисленным, поэтому вы не получите $id являющегося «foo» или другим нечисловым.