[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Проверка на sql-инъекцию
st0rk
Добрый день!
Есть сайт, был взломан через sql-инъекцию, пытаюсь защитится, чтобы в дальнейшем предотвратить такое, вроде везде поэкранировал все, но возможно и не все, хочу сам убедиться что все ок. подскажите как самому проверить страницы на простую sql-инъекцию?



Спустя 30 минут, 27 секунд (12.09.2011 - 14:38) redreem написал(а):

Спустя 21 минута, 38 секунд (12.09.2011 - 14:59) st0rk написал(а):
я читал, просто хотелось бы реальный пример получить, пробую так:
page.php?id=-99+union+select+1,pass,3,4,5+from+users
получаю что в таблице нет записей, это нормально или дыра осталась?

для id сделал типизацию: mysql_query("SELECT запрос".(int)$id."ORDER продолжение"); в строке запроса

Спустя 22 минуты, 22 секунды (12.09.2011 - 15:22) inpost написал(а):
st0rk
Если числовые данные в БД, то обрабатывай (int), если текстовые, то mysql_real_escape_string, и всё, не грозит тебе sql-inj более. Главное нигде не пропусти.

Спустя 15 минут, 17 секунд (12.09.2011 - 15:37) st0rk написал(а):
Цитата (inpost @ 12.09.2011 - 12:22)
st0rk
Если числовые данные в БД, то обрабатывай (int), если текстовые, то mysql_real_escape_string, и всё, не грозит тебе sql-inj более. Главное нигде не пропусти.

в запросе всегда число, тоесть page?id=15 например, текстовых нет как таковых.
тоесть int должен спасти?
еще есть такая страница, куда выводятся все новости подряд, в ней код выглядит примерно так:
if (!isset ($page)) {header("Location: pages_all.php?page=1"); }

далее идет просчет количества новостей, разбивка на страницы и вывод, но вот вывод меня смущает:
$page=(int)$page;
$result = mysql_query ("SELECT id,title,text,date,author,mini_img FROM news ORDER BY id DESC LIMIT $page,8");

таким способом отсечется все ненужное? пробовал в сам запрос, но что-то не получилось, пришлось до этого обьявить page как integer. так сработает?

Спустя 29 минут, 4 секунды (12.09.2011 - 16:06) inpost написал(а):
$result = mysql_query ("
SELECT `id`,`title`,`text`,`date`,`author`,`mini_img`
FROM `news`
ORDER BY `id` DESC
LIMIT "
.(int)$_GET['page'].",8
"
) or die(mysql_error());


В адресной строке (ссылке) передаётся $_GET, а не простая переменная!

Спустя 18 часов, 9 минут, 30 секунд (13.09.2011 - 10:16) st0rk написал(а):
Цитата (inpost @ 12.09.2011 - 13:06)
В адресной строке (ссылке) передаётся $_GET, а не простая переменная!

у меня в начале файла есть такая запись сразу:

if (isset ($_GET['page'])) { $page = (int)$_GET['page']; }
if (!preg_match ("|^[\d]+$|", $page)) {exit ("Not valid URL");}


дальше могу ведь в запросе не указывать .(int)$_GET['page']. , а просто $page, оно ведь должно сработать по идее.

Спустя 5 часов, 4 минуты, 24 секунды (13.09.2011 - 15:20) inpost написал(а):
st0rk
Ты считаешь адекватно вот так выдавать белый экран с какой-то левой надписью? Это некрасиво, лучше просто (int), без всяких там регулярок.

Спустя 7 минут, 40 секунд (13.09.2011 - 15:28) st0rk написал(а):
Цитата (inpost @ 13.09.2011 - 12:20)
st0rk
Ты считаешь адекватно вот так выдавать белый экран с какой-то левой надписью? Это некрасиво, лучше просто (int), без всяких там регулярок.

ок, ну если убираю регулярку, оставляю просто первую строку, это обезопасит в дальнейшем от пропуска случайного $page где забуду ему (int) прикрутить, удобнее наверно так будет или все-таки лучше по каждому запросу в каждом скрипте пройтись внимательно и везде $page поменять на (int)$_GET['page'] ?

Спустя 57 минут, 56 секунд (13.09.2011 - 16:26) inpost написал(а):
Я показал, как правильно использовать в запросе, подставлять это надо только там, если хочешь обезопасить работу с БД.
Если забудешь (int), с таким же успехом забудешь и регулярку. А вообще, не надо забывать.
(int)$var - любое значение привести к числу. Если ты вставляешь текстовое поле, то mysql_real_escape_string($var), проблем в дальнейшем не будет.

Вообще exit и die - признак плохого тона, нельзя их использовать, это только для отладки скриптов. Если человек ошибётся в адресной строке, ему всё равно надо вывести сайт, если он подставит в строку что-то типо: 'lala', то (int) вернёт 0, значит запрос твой будет LIMIT 0, и весь сайт отобразится, только данные из таблицы не выведутся, так как их нет, запрос вернул 0 выбранных строк. Чтобы было понятнее, для своей регулярке введи число 99999, и посмотри, регулярку пройдет скрипт, а вот на экран что выведется...

Спустя 2 дня, 4 часа, 8 минут, 3 секунды (15.09.2011 - 20:34) andrey888 написал(а):
все данные которые ты получаешь от пользователя должны проходить через (int), mysql_real_escape_string() соответсвенно тому что ты заносишь в БД (int) - номер , mysql_real_escape_string() - все остальное .. Если после получения и занесения в БД какой либо инфы от пользователя ты собираешься взять ее из БД и разместить где либо на сайте - пропускаем через htmlspecialchars() . Так же насчет 100% превращения в номер (int) , насколько я помню из того что читал - советуется превращать "пришедшее" в номер до вставки в запрос .. то есть к примеру не SELECT * FROM `test` WHERE `Id`=(int)$_POST["id"] ; а например вот так $id=(int)$_POST["id"]; а уже затем SELECT * FROM `test` WHERE `Id`=$id ;

Спустя 24 минуты, 34 секунды (15.09.2011 - 20:58) inpost написал(а):
"пропускаем через htmlspecialchars()" - это уже не SQL-inj, а XSS smile.gif

Спустя 2 минуты, 24 секунды (15.09.2011 - 21:01) Семён написал(а):
Подключи к своему проекту DBSimple и забудь о них (в своё время очень помогала)

Спустя 21 минута, 57 секунд (15.09.2011 - 21:23) andrey888 написал(а):
Цитата (inpost @ 15.09.2011 - 17:58)
"пропускаем через htmlspecialchars()" - это уже не SQL-inj, а XSS smile.gif

Согласен )) , просто представил как общее краткое руководство ))) . насчет подключения дополнительных вещей - некоторые любят нейтив код . ) как правильно сказал Белый Тигр в одном из постов - незачем подключать герлянду фреймворков для того для чего это не обязательно .
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.