Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Безопасно ли?


Автор: zluka 11.3.2009, 14:15
Вот простой вывод статьи из БД:
Код

if(!empty($_GET['id']))
{
    $id = intval($_GET['id']); //Приводим значение к целому числу

    $query_select = mysql_query("SELECT * FROM articles WHERE id=".mysql_real_escape_string($id)); //Экранируем все символы

    $f = mysql_fetch_array($query_select);
    
    //Вывод самой статьи
    echo "</br>";
    echo "<h3>".$f['Title']."</h3>";
    echo "<p>".$f['Text']."</p>";
}

Достаточна ли защита от SQL-инъекции?

Автор: pizzz 11.3.2009, 14:27
Код

if(!empty($_GET['id']))
{


Так не надо. Надо:

Код

if(isset($_GET['id']))
{



Автор: bars80080 11.3.2009, 14:29
после intval смысла в mysql_real_escape_string нет

Автор: pizzz 11.3.2009, 14:32
Код

$id = intval($_GET['id']); //Приводим значение к целому числу


ТО есть если ид строка. То получиться 1. Хотя запросили строку.....


Проше сделать так:

Код


if ( isset($_GET['id']) && $_GET['id'] >= 0)
{

    $query_select = mysql_query("SELECT * FROM articles WHERE id='$id'")); 
    if ( 0 != mysql_num_rows($query_select)) {

        $f = mysql_fetch_array($query_select);
    
        //Вывод самой статьи
        echo "</br>";
        echo "<h3>".$f['Title']."</h3>";
        echo "<p>".$f['Text']."</p>";
     }
}



Добавлено через 58 секунд
Голова болит... Заболел... Могу ошибаться.....

Автор: NewDima 11.3.2009, 16:41
и в конце вернулись к той же инъекции...
если $_GET['id'] - строка не число, то выражение 
Код

$_GET['id'] >= 0

всегда вернет истину а потому в 
$_GET['id'] может быть и "1' UNION ..." или "1' OR 1=1"
поправьте, если ошибаюсь

Добавлено @ 16:44
я бы использовал is_int, заодно можно хоть узнать, че нам пытаются впихать в запрос и анализировать в логах потом

Автор: O_c0der 11.3.2009, 20:56
Код

if(isset($_GET['id']) && !empty($_GET['id'])) { // Проверяем на наличие и пустоту переменную $_GET['id']
    $id = (int) $_GET['id']; // Присваиваем переменной тип int
    $query_select = mysql_query("SELECT * FROM articles WHERE id=$id"); // Запрос
    $f = mysql_fetch_array($query_select); // Получаем массив данных
    echo "</br><h3>".$f['Title']."</h3><p>".$f['Text']."</p>"; // Выводим статью
}

100% защита от атаки sql-injection

Автор: SneG0K 11.3.2009, 21:21
O_c0der, и что ты изменил? Барс все сказал... 
Если извращать по конкретному, то регулярками и на пустоту... Хотя вполне хватит и преобразования в INT...
Хотя!, на сколько мне известно что строка 1a, после преобразования к Integer, становится 1. Ну в принципе логично. НО, в параметре уже левая буква завелась, что уже значит о наличии неправильных данных и хотя в большинстве случаев мускуль вернет значение по ID, я считаю, что стоит проверять на всякое лишнее... Если программа функциклирует правильно, то левым данным в ссылке браться неоткуда... Хотя это мое мнение.

Автор: enof 11.3.2009, 21:27
SneG0K, левые данные обычно берутся не из-за неправильного функционирования системы.
Цитата(SneG0K @  11.3.2009,  21:21 Найти цитируемый пост)
Если программа функциклирует правильно, то левым данным в ссылке браться неоткуда...

и теперь не обрабатывать данные от пользователя?

развернули тут, хотя все говорят об одном и том же почти smile 
mysql_escape_string or intval и ниче не страшно

Автор: zluka 11.3.2009, 21:29
Спасибо, где целочисельный параметр я уже разобрался, а от как быть если параметр строковый:
Код

programs.php?type=windows

Использовать только mysql_real_escape_string?

Автор: bars80080 11.3.2009, 21:48
Цитата(zluka @  11.3.2009,  20:29 Найти цитируемый пост)
Использовать только mysql_real_escape_string?

угу

Автор: pizzz 12.3.2009, 05:33
Я бы его еще проверял strlen smile 

Автор: pompei 12.3.2009, 06:14
А я всегда по тупому поступаю: любые аргументы прогоняю через mysql_real_escape_string (даже целые) - 100% гарантия от sql-injection.

А чтобы не париться со всякими-там конкатенациями и не писать часто длиннющую функцию mysql_real_escape_string - я написал класс, и всегда в базу хожу так:
Код

...
$connection = getConnection();
$connection->set_sql("select * from articles where id = :id");
$connection->set_param( "id", $_GET['id'] );
$rows = $connection->execute();
...

set_param($substring, $value) - в sql-строке все подстроки (":".$substring) заменяет на mysql_real_escape_string($value)
а mysql сам преобразует строку в число если колонка целочисленная


Автор: xoma 12.3.2009, 09:15
а можно для работы  с БД просто воспользоваться http://ru.php.net/pdo

Автор: gta4kv 12.3.2009, 09:33
pizzz, спасибо поржал.

Цитата

Код

if(!empty($_GET['id']))
{


Так не надо. Надо:

Код

if(isset($_GET['id']))
{


isset при пустом id возвращает true, отличный совет вы дали.

Было бы правильнее:
Код

if( $id )
{
     // ...
}

Это универсальный способ, при отсутствие id — false, при пустом — false.

Цитата

ТО есть если ид строка. То получиться 1.

Вообще то будет 0.

И я предполагаю что в коде будет проверка на не существование записи, так что если юзер полезет корявыми руками то все равно ничего не выйдет.


zluka, 
прежде чем выводить проверяйте нашлось ли что нибудь:
Код

if( mysql_num_rows( $query ) > 0 )
{
    // ...
}


Цитата

Я бы его еще проверял strlen smile

зачем?

Цитата

Если извращать по конкретному, то регулярками и на пустоту...

Это только параноикам smile intval все равно сделает свою работу, и если переменная будет не числом в итоге будет 0, этого вроде вполне достаточно smile


Так же прошу заметить что такая конструкция:
Код

if( $id )
{
     // ...
}

не пропустила бы id = 0, ибо 0 === false

Автор: pompei 16.3.2009, 14:33
Цитата(xoma @ 12.3.2009,  09:15)
а можно для работы  с БД просто воспользоваться http://ru.php.net/pdo

абсолютно согласен

Автор: IZ@TOP 16.3.2009, 16:58
Цитата(pompei @  16.3.2009,  15:33 Найти цитируемый пост)
Цитата(xoma @ 12.3.2009,  09:15)
а можно для работы  с БД просто воспользоваться PDO

абсолютно согласен 

В mysqli тоже есть prepare.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)