Является ли этот запрос уязвимым для внедрения SQL? - PullRequest
5 голосов
/ 16 марта 2010
$myq = sprintf("select user from table where user='%s'", $_POST["user"]);

Я хотел бы знать, можно ли использовать приведенный выше запрос с помощью SQL-инъекции. Есть ли какой-нибудь продвинутый метод внедрения SQL, который может сломать sprintf для этого конкретного запроса?

Ответы [ 8 ]

25 голосов
/ 16 марта 2010

Я не думаю, что это должно быть особенно продвинутым ... попробуйте ввести

' OR 1 = 1 OR user='

Другими словами, вы получите SQL:

select user from table where user='' OR 1 = 1 OR user=''

Похоже ли это на запрос, который вы действительно хотите выполнить? (Теперь рассмотрим возможность того, что вместо этого можно будет удалить таблицы или что-то подобное.)

Суть в том, что вы должны использовать параметризованный запрос.

8 голосов
/ 16 марта 2010

Да, я бы сказал, что у вас есть потенциальная проблема там:)

Вам нужно сбежать : \x00, \n, \r, \, ', " и \x1a. sprintf () не делает этого, , sprintf() не изменяет строки, он просто расширяет любые переменные аргументы, которые вы передаете, в буфер, который вы предоставляете, в соответствии с указанным форматом.

Если строки преобразуются, это, вероятно, связано с магическими кавычками (как Роб , отмеченный в комментариях), а не sprintf(). Если это так, я настоятельно рекомендую отключить их.

8 голосов
/ 16 марта 2010

Использование 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"]));
4 голосов
/ 16 марта 2010

когда $ _POST ["user"] будет равно "'; SHUTDOWN;" - что будет?

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

На самом деле отключите магические кавычки.

В 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 еще более сложными.

Я использую все три в указанном порядке.

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

Ааа, вот и я с волшебным ответом! :)
magic quotes спасайся!

Итак, вы должны отключить директиву magic_quotes_gpc ini
и затем используйте mysql_real_escape_string как предложено.

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

Да.

Если кто-то указал в качестве пользователя следующую форму:

'; delete * from table
0 голосов
/ 16 марта 2010
$_POST["user"] = "' or 1=1 or user='"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...