PHP: Достаточно ли mysql_real_escape_string для очистки ввода пользователя? - PullRequest
58 голосов
/ 01 марта 2010

Достаточно ли mysql_real_escape_string для очистки ввода пользователя в большинстве ситуаций?

:: EDIT ::

В основном я думаю о предотвращении внедрения SQL-кода, но в конечном итоге хочу узнать, могу ли я доверять пользовательским данным после применения mysql_real_escape_string или мне следует предпринять дополнительные меры для очистки данных перед их передачей по приложению и базам данных ,

Я понимаю, где важна очистка HTML-символов, но я не считаю это необходимым для доверия пользовательскому вводу.

T

Ответы [ 10 ]

36 голосов
/ 01 марта 2010

mysql_real_escape_string недостаточно во всех ситуациях, но это определенно очень хороший друг. Решение лучше использует Подготовленные заявления

//example from http://php.net/manual/en/pdo.prepared-statements.php

$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);

// insert one row
$name = 'one';
$value = 1;
$stmt->execute();

Также не стоит забывать HTMLPurifier , который можно использовать для удаления любых недопустимых / подозрительных символов.

...........

Edit: Исходя из комментариев ниже, мне нужно опубликовать эту ссылку (я должен был сделать, прежде чем извините за создание путаницы)

mysql_real_escape_string () и подготовленные заявления

Цитирование:

mysql_real_escape_string () подвержена такие же проблемы, влияющие на addslashes ().

Крис Шифлетт (эксперт по безопасности)

11 голосов
/ 01 марта 2010

Ответ на ваш вопрос - нет. Mysql_real_escape_string () не подходит для всех пользовательских вводов, а mysql_real_escape_string () не останавливает все инъекции sql. addlashes () - еще одна популярная функция, используемая в php, и у нее та же проблема.

уязвимый код:

mysql_query("select * from user where id=".mysql_real_escape_string($_GET[id]));

Poc Exploit:

http://localhost/sql_test.php?id=1 or sleep(500)

Патч должен использовать кавычки вокруг id:

mysql_query("select * from user where id='".mysql_real_escape_string($_GET[id])."'");

Действительно, лучший подход - это использовать параметризованные запросы, на которые указали многие люди. Pdo работает хорошо, adodb - еще одна популярная библиотека для php.

Если вы используете mysql_real_escape_string, его следует использовать только для внедрения SQL, и ничего больше. Уязвимости в значительной степени зависят от того, как используются данные. Следует применять меры безопасности в зависимости от функции. И да, XSS - это ОЧЕНЬ СЕРЬЕЗНАЯ ПРОБЛЕМА . Не фильтровать html - это серьезная ошибка, которую хакер будет использовать для вас. Пожалуйста, прочитайте xss faq .

5 голосов
/ 01 марта 2010

к базе данных, да. Вы также можете рассмотреть возможность адекватного экранирования / кодирования данных для вывода.

Вы также должны рассмотреть проверку ввода против того, что вы ожидаете.

Рассматривали ли вы использование подготовленных заявлений ? PHP предлагает множество способов взаимодействия с вашей базой данных. Большинство из которых лучше, чем функции mysql_ *.

PDO , MDB2 и MySQL Improved должны помочь вам начать.

4 голосов
/ 01 марта 2010

В каких ситуациях?

Для запросов SQL это здорово.(Подготовленные операторы лучше - я голосую PDO за это - но функция просто отлично выходит.) Для HTML и т. П. Это не инструмент для работы - попробуйте общий htmlspecialchars или болееточный инструмент, такой как HTML Purifier .

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

2 голосов
/ 01 марта 2010

mysql_real_escape_string() полезно только для предотвращения атак с использованием SQL-инъекций. Это не поможет вам предотвратить атаки межсайтовых скриптов. Для этого вы должны использовать htmlspecialchars() непосредственно перед выводом данных, которые были первоначально собраны из пользовательского ввода.

1 голос
/ 12 мая 2012

Вы можете попробовать оба, как в

function clean_input($instr) {

     // Note that PHP performs addslashes() on GET/POST data.
     // Avoid double escaping by checking the setting before doing this.
    if(get_magic_quotes_gpc()) {
        $str = stripslashes($instr);
    }
    return mysql_real_escape_string(strip_tags(trim($instr)));
}
1 голос
/ 01 марта 2010

Существуют разные виды «очистки».

mysql_real_escape_string достаточно для данных базы данных, но все равно будет оцениваться браузером при отображении, если это HTML.

Чтобы удалить HTML из пользовательского ввода, вы можете использовать strip_tags .

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

1 голос
/ 01 марта 2010

Есть два способа, один - использовать подготовленные операторы (как упоминалось в других ответах), но это замедлит ваше приложение, потому что теперь вам нужно отправить два запроса в базу данных, а не один. Если вы можете жить с пониженной производительностью, тогда сделайте это; Подготовленные операторы делают ваш код красивее и проще в обращении.

Если вы решили использовать mysql_real_escape_string, то убедитесь, что вы экранировали все недоверенные строки. Экранная строка (mysql_real_escape_string) защищена SQL-инъекцией . Если вы не избежите всех строк, то вы не в безопасности. Вы должны действительно объединить mysql_real_escape_string с проверкой ввода; проверка того, что переменная, которую вы ожидаете хранить как число, действительно является числом и находится в ожидаемом диапазоне. Помните, никогда не доверяйте пользователю.

0 голосов
/ 08 июля 2010

Я думал, что добавлю, что в PHP 5.2+ есть функции фильтра ввода, которые могут дезинфицировать ввод пользователя различными способами.

Вот ручная запись , а также сообщение в блоге [от Мэтта Батчера] о том, почему они великолепны.

0 голосов
/ 01 марта 2010

Лучший способ - использовать Подготовленные заявления

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...