Поэтому в этой программе, которую я пишу, я на самом деле беру SQL-запрос от пользователя, используя форму. Затем я продолжаю выполнять этот запрос в своей базе данных.
Я не знаю, как «доверять» пользователю, поэтому я хочу сделать санитацию на входе. Я пытаюсь использовать mysql_real_escape_string
но не удалось добиться его работы.
Вот что я пытаюсь, учитывая ввод: select * from Actor;
//"query" is the input string: $clean_string = mysql_real_escape_string($query, $db_connection); $rs = mysql_query($clean_string, $db_connection); if (!$rs) { echo "Invalid input!"; }
Это ВСЕГДА дает мне
"Неправильный ввод!"
ошибка.
Когда я clean_string
часть clean_string
и запускаю mysql_query
по запросу,
"неправильный ввод"
сообщение не выводится. Скорее, когда я это делаю:
$rs = mysql_query($query, $db_connection); if (!$rs) { echo "Invalid input!"; }
Он НЕ выводит
"неправильный ввод".
Однако мне нужно использовать функцию mysql_real_escape_string
. Что я делаю не так?
Обновить:
Выбранный select * from Actor;
как вход, я нашел следующее.
Используя инструкции echo, я обнаружил, что перед дезинфекцией строка содержит значение: select * from Actor;
что правильно. Однако после дезинфекции он содержит неправильное значение select *\r\nfrom Actor;
, следовательно, сообщение об ошибке. Почему mysql_real_escape_string
делает это?
используйте его в действительных значениях в вашем запросе, а не всю строку запроса.
пример:
$username = mysql_real_escape_string($_POST['username']); $query = "update table set username='$username' ..."; $rs = mysql_query($query);
Вместо использования устаревшего расширения mysql, переключитесь на PDO . Подготовленные параметры оператора не уязвимы для инъекций, потому что они сохраняют значения отдельно от операторов. Подготовленные заявления и PDO имеют другие преимущества, включая производительность, простоту использования и дополнительные возможности. Если вам нужен учебник, попробуйте « Написание сценариев MySQL с PHP и PDO ».
mysql_real_escape_string()
– это функция экранирования строки . Он не делает никаких входных данных безопасными, просто строковыми значениями , а не для использования с предложениями LIKE, и целые числа должны обрабатываться по-разному.
Более простым и универсальным примером может быть:
$post = array_map("mysql_real_escape_string", $_POST); // cleans all input variables at once mysql_query("SELECT * FROM tbl WHERE id='$post[id]' OR name='$post[name]' OR mtime<'$post[mtime]' "); // uses escaped $post rather than the raw $_POST variables
Обратите внимание, что каждая переменная все еще должна быть заключена в одинарные кавычки для строк SQL. (В противном случае побег будет бессмысленным.)
Вы должны использовать mysql_real_escape_string
для mysql_real_escape_string
параметров для запроса, а не всего самого запроса.
Например, допустим, у вас есть две переменные, полученные из формы. Тогда ваш код будет выглядеть так:
$Query = sprintf( 'INSERT INTO SomeTable VALUES("%s", "%s")', mysql_real_escape_string($_POST['a'], $DBConnection), mysql_real_escape_string($_POST['b'], $DBConnection) ); $Result = mysql_query($Query, $DBConnection);
руководство mysql_real_escape_string ()
Вызывает специальные символы в строке для использования в инструкции SQL
Таким образом, вы не можете избежать всего запроса, просто данные … потому что он избежит всех небезопасных символов, таких как кавычки (действительные части запроса).
Если вы попробуете что-то подобное (чтобы избежать всего запроса)
echo mysql_real_escape_string("INSERT INTO some_table VALUES ('xyz', 'abc', '123');");
Выход
INSERT INTO some_table VALUES (\ 'xyz \', \ 'abc \', '' 123 \ ');
и это недопустимый запрос .
Это сработало для меня. dwolf (wtec.co)
<?php // add data to db require_once('../admin/connect.php'); $mysqli = new mysqli($servername, $username, $password, $dbname); /* check connection */ if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); } $post = $mysqli->real_escape_string($_POST['name']); $title = $mysqli->real_escape_string($_POST['message']); /* this query with escaped $post,$title will work */ if ($mysqli->query("INSERT into press (title, post) VALUES ('$post', '$title')")) { printf("%d Row inserted.\n", $mysqli->affected_rows); } $mysqli->close(); //header("location:../admin"); ?>