$myq = sprintf("select user from table where user='%s'", $_POST["user"]);
Я хотел бы знать, может ли вышеупомянутый запрос быть использован с помощью Внедрения SQL. Есть ли любой усовершенствованный метод Внедрения SQL, который мог повредиться sprintf
для этого конкретного запроса?
Да, я бы сказал, у вас есть потенциальная проблема :)
Вам нужно сбежать : \ x00, \ n, \ r, \, ', "
и \ x1a
. sprintf () не делает этого , sprintf ()
не модифицирует строки, он просто расширяет любые переменные аргументы, которые вы даете ему, в предоставленный вами буфер в соответствии с указанным вами форматом.
Если строки преобразуются, это, вероятно, связано с волшебные цитаты (как Роб отметил в комментариях), а не sprintf ()
. Если это так, я настоятельно рекомендую отключить их.
Я не думаю, что это должно быть особенно сложным... попробуйте ввести
' OR 1 = 1 OR user='
Другими словами, вы получите SQL вида:
select user from table where user='' OR 1 = 1 OR user=''
Похоже ли это на запрос, который вы действительно хотите выполнить? (Теперь подумайте о возможности того, что вместо этого он будет сбрасывать таблицы или что-то подобное)
Суть в том, что вы должны использовать параметризованный запрос.
когда $_POST["user"] будет равен "';SHUTDOWN;" - что произойдет?
А вот и я с волшебным ответом! :)
волшебные кавычки
делают побег за вас!
Итак, вам нужно отключить директиву magic_quotes_gpc ini
и затем использовать mysql_real_escape_string, как было предложено.
Да.
Если кто-то вставил следующее в качестве пользователя в вашу форму:
'; delete * from table
Вообще-то отключите волшебные цитаты.
В PHP, где это уместно, используйте фильтры:
$inUser = $_POST['user'];
$outUser = filter_var($inUser, FILTER_SANITIZE_STRING);
Фильтры удаляют теги HTML и экранируют различные символы.
Кроме того, вы можете позволить базе данных избежать этого за вас:
$inUser = $_POST['user'];
$outUser = mysqli_real_escape_string($conn, $inUser);
Это позволяет избежать специальных символов MySQL, таких как двойные кавычки, одинарные кавычки и т. Д.
Наконец, вы должны использовать параметризованные запросы:
$sql = "SELECT user FROM table WHERE user = ?";
$stmt = $pdo->prepare($sql);
$params = array($outUser);
$stmt->execute($params);
Параметризованные запросы автоматически добавлять кавычки вокруг строк и т. д. и иметь дополнительные ограничения, которые еще больше затрудняют внедрение SQL.
Я использую все три в таком порядке.
Использование sprintf
не дает вам больше защиты, чем использование простой конкатенации строк. Преимущество sprintf
заключается лишь в том, что он немного более читабелен, чем при использовании простой конкатенации строк PHP. Но sprintf
делает не больше, чем простая конкатенация строк при использовании формата %s
:
$str = implode('', range("\x00", "\xFF")); // string of characters from 0x00 – 0xFF
var_dump(sprintf("'%s'", $str) === "'".$str."'"); // true
Вам нужно использовать функции, которые экранируют контекстные специальные символы, в которые вы хотите вставить ваши данные (в данном случае строковое объявление в MySQL, предполагая, что вы используете MySQL), как это делает **mysql_real_escape_string**
например:
$myq = sprintf("select user from table where user='%s'", mysql_real_escape_string($_POST["user"]));