IP-адрес SQL-инъекции
Возможно ли, что пользователь может подделать результат, который возвращается из $_SERVER['REMOTE_ADDR']
в PHP, чтобы теоретически использовать SQL-инъекцию в базе данных?
Это немного глупо, но я до сих пор достаточно доволен PHP, который я хочу знать, может ли это быть сделано, нужно ли мне дезинфицировать ввод базы данных, когда оператор SELECT
выбирает из IP-адресов, возвращенных из $_SERVER['REMOTE_ADDR']
. Итак, если бы я хотел использовать что-то вроде $query = "SELECT * FROM users WHERE IP='" . $_SERVER['REMOTE_ADDR'] . "'";
, была бы какая-то опасность для этого?
Опять же, вероятно, вопрос "nooby", но я чувствую, что его нужно спросить.
Спасибо
Ответы
Ответ 1
Это растянуто, и маловероятно, но я бы не стал так говорить, что это невозможно. Так....
Использовать параметризованные запросы в любом случае.
Даже если вы никогда не атакуетесь через поле IP-адреса, вы все равно получите дополнительное преимущество от более быстрых запросов с помощью кеширования.
Ответ 2
Вы не можете полагаться на REMOTE_ADDR, являющийся истинным... это может быть неправильный адрес из-за анонимных прокси или какой-то такой трюк. Вы можете полагаться на то, что он всегда является IP-адресом, поэтому SQL-инъекция по этому пути невозможна.
Путь вниз в нижней части стека, который был преобразован из исходного адреса в пакеты, создающие соединение TCP с вашим сервером. Это означает, что a) он должен быть IP-адресом, и b) ему нужно отправить обратно клиенту, чтобы соединение вообще произошло.
Ответ 3
Я думаю, что единственный способ для кого-то подделать $_SERVER['REMOTE_ADDR']
- это построить IP-пакет с поддельным IP-адресом (потому что он установлен сервером, а не клиентом), и в этом случае ответы будут перенаправлены обратно поддельный адрес. Если вас беспокоят атаки на инъекции, я думаю, что вы в порядке, потому что в полях адреса в IP-пакетах есть только место для адресов.
Ответ 4
Всегда санируйте все внешние входы - используйте mysql_real_escape_string
или еще лучше, подготовленные заявления
Ответ 5
Вы можете использовать функции фильтрации данных PHP.
filter_var() с FILTER_VALIDATE_IP будет проверять удаленный IP-адрес. Если удаленный IP действителен, используйте его в SQL.
EDIT: filter_input() с INPUT_SERVER - еще одна опция;)
http://www.php.net/manual/en/book.filter.php
http://www.php.net/manual/en/filter.filters.validate.php
http://www.php.net/manual/en/function.filter-var.php
http://www.php.net/manual/en/function.filter-input.php
Надеюсь, что это поможет,
Симеон
Ответ 6
Я всегда ставил этот код во все мои проекты (некоторая начальная санация ввода), чтобы предотвратить что-то противное с поддельными IP-адресами.
Я не уверен, могут ли они подделать REMOTE_ADDR в любом случае.
function validate_ip($ip) {
// Try IPv4 First, as its the most used method right now
if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
// Oops... try v6
if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
return false; // Sorry...
}
else {
return true;
}
}
else {
return true;
}
}
if(!isset($_SERVER['REMOTE_ADDR'])) # wtf?
die("Could not find your IP Address...");
else {
if(validate_ip($_SERVER["REMOTE_ADDR"]))
die("Could not validate your IP Address...");
}
Ответ 7
REMOTE_ADDR не отправляется клиентом, он устанавливается сервером. Хотя технически возможно обмануть IP-адрес на сетевом уровне, злоумышленник должен работать слепым. Самая сложная часть - это догадка порядковый номер. (Под Coldfusion, кстати, другая история.)
Как говорили другие, используйте подготовленные инструкции, и вам не нужно беспокоиться о внедрении SQL (хотя возможны и другие типы инъекционных атак).
Ответ 8
Для обеспечения эффективности и безопасности вы можете захотеть сохранить и работать с IP-адресами как ints в своей базе данных.
Простым способом хранения IP-адресов является использование поля varchar в вашей базе данных. Однако другой способ представления IP-адресов является целым числом. Преобразование поставляемого IP таким образом будет дезинфицировать его, а также повысить эффективность хранения и запросов. Хранение INT занимает меньше места в БД и лучше работает для индексирования, и я считаю, что кеширование запросов.
Отметьте ip2long и long2ip для функций PHP для преобразования, а inet_aton и inet_ntoa сделать это в MySQL.
Итак, процесс может выглядеть как
$user_ip=ip2long($_SERVER['REMOTE_ADDR']);
if(!$user_ip){ //returned false due to odd input
echo 'wtf, yo';
}
else{
//do your query
}
Вы также можете дезинфицировать IP-адрес и сохранить его в исходной квадратной форме, объединив два
$user_ip=long2ip(ip2long($_SERVER['REMOTE_ADDR']));