2011-01-13 4 views
4

Является ли этот код 100% гарантией безопасности от инъекции SQL:Это безопасный способ защитить от SQL-инъекции?

$id = $_GET['id'] 
mysql_query('SELECT * FROM mytable WHERE id < ' . (int)$id); 

или я должен делать это?

$id = $_GET['id'] 
mysql_query('SELECT * FROM mytable WHERE id < ' . mysql_real_escape_string($id)); 
+0

В вашем втором блоке кода есть отверстие для SQL-инъекции, потому что вы не дважды указывали вывод из 'mysql_real_escape_string()'. – Johan

ответ

2

Запрос может по-прежнему взорваться, если $_GET['id'] пуст или (int)$_GET['id'] оценивает наличие на складе. В результате вы получите синтаксическую ошибку в запросе. Недостаточно слепо бежать или вводить значение типа и вводить его в запрос. Вы должны проверить, что окончательное «безопасное» значение действительно безопасно, а не только волка в одежде бабушки.

0

Я использую sprintf, mysql_query(sprintf('SELECT * FROM mytable WHERE id < %d', $id));

+0

Это не очень безопасно, потому что если $ id не является int, он будет преобразован в int. Что, если $ id = "xyz", тогда это будет "SELECT * FROM mytable WHERE id <0" –

+0

@Amir Raminfar: Он говорит, чтобы предотвратить инъекцию sql, и это работает. Кастинг не проблема в этот момент, я думаю. – Cesar

+1

Нет, это не сработало, потому что если это было DELETE * FROM mytable WHERE id>% d, то я могу удалить его, просто выполнив id> 0. Не так хорошо !!! –

-1

Это безопасно, но вы, вероятно, хотите сделать

if(is_int($id)){ 
mysql_query('SELECT * FROM mytable WHERE id < ' . mysql_real_escape_string($id)); // just to be safe always to escape 
} 
+1

Я только думаю, что это лучше, потому что вы хотите изящно потерпеть неудачу, вместо того, чтобы иметь сломанное приложение, когда $ id не является int –

2

Это

mysql_query('SELECT * FROM mytable WHERE id < ' . mysql_real_escape_string($id)); 

будет плохая практика. Если вы хотите, чтобы быть строка, по крайней мере процитировать строку:

mysql_query('SELECT * FROM `mytable` WHERE `id`<"'.mysql_real_escape_string($id)).'"'; 

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

Я бы предпочел бросок, если он является целым числом. Один аргумент для строковой версии состоял бы в том, что в какой-то день идентификатор может быть буквенно-цифровым (как это видно все чаще на многих веб-сайтах).

0

Вы должны использовать параметризованные запросы. Тогда вам не нужно беспокоиться обо всем, что ускользает. Это также упрощает чтение SQL. О, и не используйте select *, просто выберите то, что вы хотите.

0

Нет
вы должны сделать это:

$id = mysql_real_escape_string($_GET['id']); 
//put the escaped string in a $var, so your select statement stays readable 
//this will help in debugging, and make **not** forgetting those vital quotes 
//easier. 
$query = "SELECT * FROM mytable WHERE id < '$id'"; 
//          ^ ^always single quote your $vars 
//  ^         ^and double quote the query 
$result = mysql_query($query); 
//and test to see if your query ran successful. 
if (!$result) { //your query gave an error, handle it gracefully. 

Тогда вы в безопасности.

+0

Ответ на старый вопрос. Как упоминалось в других ответах: используйте параметризованные запросы. – Nanne

+0

Это малоприменимо, повторяя ответы всех elses, это способ сделать mysql_real_escape_string() безопасным. Нет сомнения, что PDO лучше. Но, учитывая неправильное использование этой функции с этим действительно длинным именем, я подумал, что хочу указать, как он должен работать. – Johan

+0

Зачем давать советы, чтобы вы не могли следовать, не отвечая на фактический вопрос (см. Обсуждение моего ответа). Ваше «нет» все еще странно для меня. но я оставлю вас на ваших выводах, хотя, думаю, неправильно, что вы получили мой ответ с -1. – Nanne

Смежные вопросы