Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: возможен ли взлом?
 
 автор: technic611   (08.11.2014 в 18:39)   письмо автору
 
 

решил проверить сайт на уязвимость так называемая инъекция. сделал все как пишут на форумах. подставил двойную кавычку в конце
finance.php?edituser&id=31"

и получил ошибку
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"' at line 1
SELECT * FROM `users` WHERE `id` = 31"


также решил подставить вконце finance.php?edituser&id=31;

и получил тоже ошибку
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ORDER BY `id` DESC LImit 0,10' at line 1
SELECT * FROM `operations` WHERE `user_id` = 31; ORDER BY `id` DESC LImit 0,10


в коде у меня так SELECT * FROM `users` WHERE `id`='{$_GET['id']}'
это опасно? что нужно сделать чтобы защититься?

  Ответить  
 
 автор: confirm   (08.11.2014 в 20:08)   письмо автору
 
   для: technic611   (08.11.2014 в 18:39)
 

> в коде у меня так SELECT * FROM `users` WHERE `id`='{$_GET['id']}'

В коде должно быть типа такого:

<?
if($id = (int)$_GET['id']) //запрос по $id


а WHERE `id`= $_GET['key'] - это и есть "ворота" для инъекции.

  Ответить  
 
 автор: technic611   (08.11.2014 в 20:33)   письмо автору
 
   для: confirm   (08.11.2014 в 20:08)
 

т.е. нужно указать перед запросом такую проверку? или непосредственно в запрос поставить (int)? а как можно узнать пароли используя мою уязвимость?

  Ответить  
 
 автор: confirm   (08.11.2014 в 21:02)   письмо автору
 
   для: technic611   (08.11.2014 в 20:33)
 

>т.е. нужно указать перед запросом такую проверку? или непосредственно в запрос поставить (int)?

А давайте я попробую угадать - WHERE `id`, это запрос по первичному ключу с автоинкрементом, так?

Вопрос - может ли быть первичный ключ с автоинкрементом равный 0?

А если нет и ($id = (int)$_GET['id'] возвращает 0 (если "подстава"), стоит ли выполнять запрос заведомо зная, что таких записей в базе нет?

И так - до запроса нужно делать эту проверку, как условие для запроса, или же сразу в теле запроса производить преобразование тем самым делая запрос никчемный?

> а как можно узнать пароли используя мою уязвимость?

Читайте - это минимум, который вы обязаны знать.

PS. Инъекция, это не обязательно ради паролей.

  Ответить  
 
 автор: technic611   (08.11.2014 в 22:53)   письмо автору
 
   для: confirm   (08.11.2014 в 21:02)
 

а как сделать проверку если я подставил впереди минус? id=-20

if(!($page2=(int)preg_replace('/[^0-9]++/u','',@$_GET['page'])))die('неверный запрос');
посмотрите пожалуйста правильно ли я проверю на эти числа

кстати ваша проверка у меня не срабатвает...

  Ответить  
 
 автор: confirm   (09.11.2014 в 09:11)   письмо автору
 
   для: technic611   (08.11.2014 в 22:53)
 

Узнать - проверить меньше ли нуля, получить - взять абсолютное значение.

А ваша "проверка" preg_replace('/[^0-9]++/u',''... - это бессмысленное никчемное занятие.

  Ответить  
 
 автор: technic611   (09.11.2014 в 11:34)   письмо автору
 
   для: confirm   (09.11.2014 в 09:11)
 

можете показать пример реальной проверкой? потому что ваш совет он все равно показывает ошибки. может быть проверять на вредоносные слова?

  Ответить  
 
 автор: confirm   (09.11.2014 в 12:04)   письмо автору
 
   для: technic611   (09.11.2014 в 11:34)
 

Какие ошибки?

Я спрашивал - поле id, это уникальный номер?

А если так, то что будет истиной в данных - только номер или все что угодно? А если только номер, то на кой ляд нужно preg_replace()? Зачем собака?

<?
//не инициализированные переменные
var_dump($var); //получаем null
var_dump($_GET['id']); //получаем null, если массив $_GET пуст, то есть не было передачи данных
//преобразование
echo (int)null//получаем 0
echo (int)false//получаем 0
echo (int)true//получаем 1
//с учетом не пропустить и отрицательные значения
//1) запустить сразу - результат нулевой
//2) $_GET['id'] = -2; и потом запустить - результат тоже нулевой
//3) $_GET['id'] = 2; и потом запустить - получим результат
if($id = (int)$_GET['id'] AND $id 0) {
    echo 
"Запрос";
}


Проверка число или нет, это еще и is_numeric. Преобразование в число это и intval(). Но ни в коем случае не:

<?
if(intval($_GET['id'])) {
    
//и подставляем в запрос $_GET['id']
    //подумайте почему?
}


Это все для чисел, для строк, это экранирование. И еще фильтры.

  Ответить  
 
 автор: technic611   (09.11.2014 в 12:20)   письмо автору
 
   для: confirm   (09.11.2014 в 12:04)
 

number_request=(int)$_GET['id'];
if($number_request>0) {
$sql = "SELECT * FROM `". REQUEST_TABLE. "` WHERE id='$number_request'";
     $res = mysql_query($sql) or die(mysql_error());
    } 
     


посмотрите так?

  Ответить  
 
 автор: confirm   (09.11.2014 в 12:47)   письмо автору
 
   для: technic611   (09.11.2014 в 12:20)
 

А вы что и далее собираетесь использовать $number_request? Зачем это разделять, и зачем обрамлять число в кавычки - id='$number_request', это уже лишнее. Да и имя переменной длиной с портянку, которая в базе вполне лаконична (id), это тоже для чего?

  Ответить  
 
 автор: technic611   (09.11.2014 в 15:48)   письмо автору
 
   для: confirm   (09.11.2014 в 12:47)
 

не понял вопроса про number_request!?
насчет кавычек не знаю почему, пишут так на форумах. может это для числовых значений не нужно?
про переменнную id тоже не особо понял, нужно поменять название?

объясните я правильно понимаю сейчас если даже введут текст и какие-то запрещенные знаки, то из текста выдернется только число и скрипт должен отработать также как и обычно?
а в чем не верна конструкция с регулярным выражением, оно ведь тоже пропускает только числа. я ее не сам придумал, а взял с одного форума

  Ответить  
 
 автор: confirm   (09.11.2014 в 22:36)   письмо автору
 
   для: technic611   (09.11.2014 в 15:48)
 

Назвали вы функцию "eq", что она делает можете помнить пока ее писали, а потом и с бутылкой не разберетесь. Другое дело, если она будет называться "execute_query", одно имя функции говорит о назначении ее.

Вы пишите:

number_request=(int)$_GET['id']; //здесь ошибка

if($number_request>0) {
....
}

для чего? Это несет какую-то смысловую нагрузку или обусловлено требованиями какими-то?

Зачем отдельной строкой одну переменную присвоить другой, причем с пояснениями "number" - это число "request" пришедшее запросом, и только следующим действием проверить условие? То есть, именуя поле таблицы как id вы совсем не имеете представления что это за поле или без этого пояснения (number_request) на время написания одной строчки скрипта можете забыть о назначении $_GET['id']?

Вы определяете переменную для которой время жизни как "мгновение", это уже чрезмерно большая величина. И поступая таким образом, вы заставляете скрипт "скушать" лишние байты памяти, более ничего.

Гораздо больше было бы пользы, если для сокрытия истинных имен полей таблицы полю формы дали бы имя "number_request", которое бы скрипт ассоциировал с именем колонки "id" таблицы. Если вы все-таки удосужились изучить раздел "Безопасность", то должны понимать, что наряду с вываливанием ошибок клиенту дарить ему еще таким образом и практически структуру базы своей, это плохо.

И для задачи вашей максимум что нужно, это:

<?
if($n = (int)$_GET['id'] AND $n 0)


И лишь потому, что нам нужно использовать приведенное к типу значение и сократить имя для дальнейшего употребления. Размазывать это действие на две строки кода такое же пустое занятие, как и обрамлять числовое значение кавычками - необходимости в этом нет.

Кроме того, что пишут на форумах, есть куда более авторитетный источник - руководство РНР, изучайте. Я же могу допустить ошибку, могу начать мысль об одном, но так и не закончить по какой либо причине, оставив на форуме ошибку, и хорошо, если кто-то заметит и исправит, а если нет?

Выпендриваться с регулярным выражением в данной операции, это вообще глупость, ибо вам не разбор строки нужен, а приведение значения к требуемому типу, и это будет работать "по короткому условию" - если первый символ, это не число, значит 0, на этом и закончили, и не будет разбирательства, что еще за буковки после первой попавшей за числом буковке. Регулярные выражения при беспричинном их использовании, это зло.

Требуется принять массив значений, которые определяют записи и по которым связаны принадлежащие им файлы. По полученным значения нужно удалить записи и их файлы, и вывести сообщение:

<?
if($del implode(','array_diff(array_map('intval'$_POST['name']), array(0)))) {
    
$q 'DELETE FROM table WHERE id IN(' $del ')';
    if(
$files glob('path/{' $del '}_*'GLOB_BRACE)) while($f array_pop($files)) unlink($f);
    
$del closeEmpty(); //return message
}
.....
output('Message' $del);


Зачем это все размусоливать на отдельные по строкам инструкции? Если порождаем осмысленные переменные, значит они нужны в дальнейшем, причем могут использоваться в разных ипостасях, иначе какой прок от простой писанины слов.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования