Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> sql инъекции, подскажите кто как борется ?  
V
    Опции темы
trigger
Дата 26.9.2007, 10:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 12.7.2006

Репутация: нет
Всего: нет



Приветствую. 

вчера обнаружил что простой инъекцией можно не только очистить содержимое таблиц, но и удалять таблицы.
данные передаются get.ом. В основном это только цыфры - IDшники таблиц и т.д.
Подскажите плз что сделать, чтобы обезопасить приложение от подобных случаев.

и на сколько достаточно будет следующее:

Код


my $id = parse(param('some_id'));

sub parse {
    my $dirty = shift;
    $dirty =~s/\D//ig;
    my $clear = $dirty;
    return $clear;
}


Это сообщение отредактировал(а) trigger - 26.9.2007, 13:47
PM MAIL WWW ICQ   Вверх
nitr
Дата 26.9.2007, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 12
Всего: 84



trigger, прочесть надо perldoc DBI, затем доку по драйверу к БД mySQL (или что используете).
Ещё можно посмотреть метод quote(); - экранирует спец. символы...
Ещё стоит пересмотреть ваше "приложение", т.к. передавать данные через запросы, т.е. к примеру, db.pl?insert=...&table=... , что-то подобное, это "совсем не есть гуд" smile

Я, например, использую CGI::Application, пишу свои плагины (если требуется) и т.п. Многие скажут, что лучше воспользоваться Catalyst. К чему я вел, прочитайте про фреймворки, меньше мороки будет, да и (если в случае успеха) получите отличные "проекты"... Но это за рамками данной темы.

Добавлено через 1 минуту и 53 секунды
Да и по-гуглить стоит, слишком много лит-ры по этой теме.


--------------------
PM   Вверх
comtat
Дата 26.9.2007, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1310
Регистрация: 2.5.2006
Где: Россия, Казань

Репутация: нет
Всего: 71



Самый действенный и простой способ защиты от sql инъекций - это 
перед выполнением запроса проверять соответствие входных данных типу. Если есть несоответствие 
то нечего не записываем и тд.
У меня делается это примерно так, через свой класс  
Код

$dbAction = new Action("таблица", "primary_key", $id);
$dbAction->setString("Поле1", $value1);
$dbAction->setInt("Поле2", $value2);
..
#действие 
$dbAction->save();
 
Для каждого поля теперь определен свой тип 
и перед выполнением делается проверка
Код

sub sqlTransform(){
  my $self  = shift;
...
  foreach my $key (keys %{$arValues{"intnull"}}){
    $arValues{intnull}{$key} = int($arValues{int}{$key})?int($arValues{int}{$key}):"NULL";
  }
...
}


И все .. При том не разу не подводило ;)


--------------------
Рожденный в СССР !!!
ExtJS - мой фреймворк 
PM   Вверх
biophreak
Дата 1.10.2007, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 13.5.2007

Репутация: нет
Всего: нет



Я, например делаю так:
Определю, что должно и не должно передаваться в конкретном запросе...
Далее вырезаю все не нужно по принципу ~s///; =)
Гемморно конечно мониторить каждый запрос, но что делать. smile
PM MAIL ICQ Jabber   Вверх
trigger
Дата 1.10.2007, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 12.7.2006

Репутация: нет
Всего: нет



Благодарю всех за рекомендации ) .

Жаль, что кроме как перелопачивание входящих данных - другого пути нет! 
... будем резать будем бить ....

PM MAIL WWW ICQ   Вверх
xtrasns
Дата 3.1.2008, 09:01 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 38
Регистрация: 13.5.2007

Репутация: нет
Всего: нет



Цитата(nitr @ 26.9.2007,  14:24)
trigger, прочесть надо perldoc DBI, затем доку по драйверу к БД mySQL (или что используете).
Ещё можно посмотреть метод quote(); - экранирует спец. символы...
Ещё стоит пересмотреть ваше "приложение", т.к. передавать данные через запросы, т.е. к примеру, db.pl?insert=...&table=... , что-то подобное, это "совсем не есть гуд" smile

Я, например, использую CGI::Application, пишу свои плагины (если требуется) и т.п. Многие скажут, что лучше воспользоваться Catalyst. К чему я вел, прочитайте про фреймворки, меньше мороки будет, да и (если в случае успеха) получите отличные "проекты"... Но это за рамками данной темы.

Добавлено @ 14:25
Да и по-гуглить стоит, слишком много лит-ры по этой теме.

можно попдробнее, что за метод  quote(); ?? Я его в доках  не нашел ... 
PM MAIL   Вверх
nitr
Дата 3.1.2008, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 12
Всего: 84



xtrasns, и снова вы smile
Во-первых, вы поднимаете тему, которая явно "решена", во-вторых, в документации она есть, вы очень невнимательны.

perldoc DBI

а ещё, купите вы наконец-то книги по Perl, даже там есть хоть и короткое, но правильное определение smile

Добавлено через 2 минуты и 18 секунд
Цитата

quote 
  $sql = $dbh->quote($value);
  $sql = $dbh->quote($value, $data_type);

Quote a string literal for use as a literal value in an SQL statement, by escaping any special characters (such as quotation marks) contained within the string and adding the required type of outer quotation marks.
  $sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
                $dbh->quote("Don't");

For most database types, quote would return 'Don''t' (including the outer quotation marks).

An undefined $value value will be returned as the string NULL (without single quotation marks) to match how NULLs are represented in SQL.

If $data_type is supplied, it is used to try to determine the required quoting behaviour by using the information returned by type_info. As a special case, the standard numeric types are optimized to return $value without calling type_info.

Quote will probably not be able to deal with all possible input (such as binary data or data containing newlines), and is not related in any way with escaping or quoting shell meta-characters.

It is valid for the quote() method to return an SQL expression that evaluates to the desired string. For example:
  $quoted = $dbh->quote("one\ntwo\0three")

may return something like:
  CONCAT('one', CHAR(12), 'two', CHAR(0), 'three')

The quote() method should not be used with Placeholders and Bind Values.


Добавлено через 2 минуты и 38 секунд
Это всё в документации...


--------------------
PM   Вверх
ginnie
Дата 6.1.2008, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 4
Всего: 49



Уважаемые коллеги!

Я использую placeholders и считаю это самым эффективным средством от SQL injection, в редких случаях, когда их использование невозможно, приходится "изобретать велосипеды"  smile 


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
nitr
Дата 7.1.2008, 00:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 12
Всего: 84



ginnie, конечно это вариант. Но не всегда может применяться, да и бывает неудобно, но многие их используют, всем известно из документации, что оно сразу подставляется "экранированным" smile


--------------------
PM   Вверх
ginnie
Дата 7.1.2008, 02:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 4
Всего: 49



Уважаемый nitr, позвольте добавить, что placeholders используются после лексического разбора запроса СУБД, поэтому наличие или отсутствие "экранирования" уже никак на возможность использования SQL injection не влияет.

P.S. Функциональность справедлива для СУБД, которые поддерживают placeholders.

Это сообщение отредактировал(а) ginnie - 7.1.2008, 02:30


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
nitr
Дата 7.1.2008, 02:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 12
Всего: 84



Спасибо за разъяснение smile

Моё рассуждение актуально для bind.


--------------------
PM   Вверх
ginnie
Дата 7.1.2008, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 4
Всего: 49



Чтобы не быть голословным привожу пример своего кода, использующего placeholders

Код

use CGI qw(:cgi);
use DBI qw(:sql_types);
use locale;
use POSIX qw(locale_h);
setlocale(LC_CTYPE, q{ru_RU.cp1251});
...
my $cgi = CGI->new();
my $group_id = ( defined $cgi->param( q{group_id} ) and $cgi->param( q{group_id} ) =~ /(\d+)/o ) ? $1 : 0;
my $surname = ( defined $cgi->param( q{surname} ) and $cgi->param( q{surname} ) =~ /(\w+)/o ) ? $1 : q{};
...
my $dbhw = DBI->connect( $ENV{DBW_DSN}, $ENV{DBW_USER}, $ENV{DBW_PASS}, { AutoCommit => 1, PrintError => 0, RaiseError => 1, LongReadLen => 500000});
...
eval {
    $dbhw->begin_work(); # начинаем транзакцию
    my $query = q{
        INSERT INTO nntp_messages (group_id, thread_id, parent_id, nntp_id, title, author_name, author_email, body,
            coming_date, original_message, message_number, publishing_date, x_ftn_message_id)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, now(), ?, ?, from_unixtime(?), ?)
    };
    my $max_number = $message->get_number();
    my $sth = $dbhw->prepare($query);
    $sth->bind_param( 1, $group_id, SQL_INTEGER );
    $sth->bind_param( 2, $thread_id, SQL_INTEGER );
    $sth->bind_param( 3, $parent_id, SQL_INTEGER );
    $sth->bind_param( 4, $message->get_nntp_id(), SQL_VARCHAR );
    $sth->bind_param( 5, $message->get_title(), SQL_VARCHAR );
    $sth->bind_param( 6, $message->get_author_name(), SQL_VARCHAR );
    $sth->bind_param( 7, $message->get_author_email(), SQL_VARCHAR );
    $sth->bind_param( 8, $message->get_body(), SQL_BLOB );
    $sth->bind_param( 9, $message->get_original_message(), SQL_BLOB );
    $sth->bind_param( 10, $max_number, SQL_INTEGER );
    $sth->bind_param( 11, $message->get_date_unixtime(), SQL_INTEGER );
    $sth->bind_param( 12, $message->get_x_ftn_message_id(), SQL_VARCHAR );
    if ( $sth->execute() eq q{0E0} ) {
        Exception::DB::InsertFailed->throw(
            error   => sprintf( q{cannot add message number %s from %s}, $message->get_number(), $group->get_name() ),
        );
    }
    $dbhw->commit();
};
if ( my $exception = Exception::Class->caught() ) {
    $dbhw->rollback();
    if ( ref $exception ) {
        $exception->rethrow();
    }
    else {
        Exception::DB->throw(
            error   => sprintf( q{%s. Group: %s, message number: %d}, $@, $message->get_group()->get_name(), $message->get_number() ),
        );
    }
}
...


Это сообщение отредактировал(а) ginnie - 7.1.2008, 12:40


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
Vaneska
Дата 10.1.2008, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 141
Регистрация: 15.3.2005
Где: Москва

Репутация: 1
Всего: 4



Есть еще способ, используемый как доп. защита и по большей части красивость для пользователя.
Он больше не к перлу правда относится.
Для этого способа нужен apache и mod_rewrite
Вот пример.
Допустим есть у нас каталог какого-то товара.
Мы хотим вывести на страничку товар с id = 123
для этого в вводим в строку запроса браузера такой url
mysite.ru/catalog/good/123
в перле обрабатываем этот урл и получаем нужный id

В .htaccess задается такая строчка
Код

RewriteRule ^catalog[\/a-z0-9]*$ /cgi-bin/catalog.cgi [L]

эта строчка позволяет обросить все лишние символы.
валидными урлами становятся например
mysite.ru/catalog/group/123 (список товаров в группе)
mysite.ru/catalog/good/delete/123 (удаление товара)

Таким способом можно безболезненно передавать в бд любые числовые параметры и те символьные, которые проходят регексп.

Так что в принципе можно и не проверять эти параметры.

А вообще я использую все 3 способа одновременно.
1. Этот способ
2.  проверка входных параметров с помощью специальной функции вида
Код

$clear_param = clear(<type>, <dirty_param>)
# type - некий тип данных. Например, js_string.

3.  placeholders 

--------------------
http://isokolov.blogspot.com/
PM MAIL ICQ   Вверх
frenkys
Дата 13.1.2008, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 18.6.2005

Репутация: нет
Всего: 1



Вот еще как вариант вставлять переменные после компиляции мускула

Код

$query = "INSERT INTO fd_fmmes (id,sender,message,date) VALUES (?,?,?,NOW())";
$sth=$dbh->prepare($query) || quit($query);
$sth->execute($tid,$lo,$message) || quit($query);

--------------------
 niva[frenky]
PM MAIL WWW   Вверх
DSCL
Дата 12.2.2008, 11:13 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 12.2.2008

Репутация: -1
Всего: нет



Кто хочет теорию по атаке SQL - injection ?  smile 
PM MAIL   Вверх
trigger
Дата 12.2.2008, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 12.7.2006

Репутация: нет
Всего: нет



..

Это сообщение отредактировал(а) trigger - 12.2.2008, 13:55
PM MAIL WWW ICQ   Вверх
BlackLFL
Дата 20.3.2008, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 3
Всего: 12



Как уже упоминал ginnie, применение placeholders, действительно является самым эффективным способом, особенно для базы данных Oracle ( увеличение производительности )
PM WWW   Вверх
gcc
Дата 28.9.2010, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: 2
Всего: 17



подскажите, пожалуйста, есть большая очень нагрузка на index.pl и именно очень сильно на CPU
но на MySQL - "0" нагрузки
все работает в CGI


для того чтобы MySQL экранировала используя параметрические запросы, нужно включить mysql_server_prepare=1 ?

Код

$dbh = DBI->connect( "DBI:mysql:database=test;host=localhost;mysql_server_prepare=1", "", "", { RaiseError => 1, AutoCommit => 1 } );


ВОПРОС:
... без этого сам perl тратит много ресурсов на экранирование??


http://search.cpan.org/~capttofu/DBD-mysql...ib/DBD/mysql.pm
Цитата

Prepared statement support (server side prepare)

As of 3.0002_1, server side prepare statements were on by default (if your server was >= 4.1.3). As of 3.0009, they were off by default again due to issues with the prepared statement API (all other mysql connectors are set this way until C API issues are resolved). The requirement to use prepared statements still remains that you have a server >= 4.1.3

To use server side prepared statements, all you need to do is set the variable mysql_server_prepare in the connect:

$dbh = DBI->connect( "DBI:mysql:database=test;host=localhost;mysql_server_prepare=1", "", "", { RaiseError => 1, AutoCommit => 1 } );

* Note: delimiter for this param is ';'

There are many benefits to using server side prepare statements, mostly if you are performing many inserts because of that fact that a single statement is prepared to accept multiple insert values.

To make sure that the 'make test' step tests whether server prepare works, you just need to export the env variable MYSQL_SERVER_PREPARE:

export MYSQL_SERVER_PREPARE=1


Добавлено @ 23:57
кстате, а что вот это такое имеется ввиду??

Цитата

* Note: delimiter for this param is ';'


... что этот знак ';' не экранируется?

и что тут
Код

  $db->Exec("UPDATE Files SET file_fld_id=? WHERE usr_id=? AND file_id IN 
      (".join(',',@{$f->{file_id}}).")",$fld_id,$ses->getUserId);

будет инъекция? в IN ?
http://forum.vingrad.ru/forum/topic-309184.html

или нет?


Это сообщение отредактировал(а) gcc - 29.9.2010, 00:10
PM WWW ICQ Skype GTalk Jabber   Вверх
steyraug
Дата 27.10.2010, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.8.2010

Репутация: нет
Всего: нет



А что народ скажет насчет применения функции int() к переданному GET-параметру?

Это сообщение отредактировал(а) steyraug - 27.10.2010, 22:43
PM MAIL   Вверх
ming
Дата 28.10.2010, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 30.1.2009
Где: Новосибирск

Репутация: нет
Всего: 3



а что тут скажешь? для целочисленных данных может и сгодится, а для строковых int бессилен
PM MAIL ICQ Jabber   Вверх
steyraug
Дата 1.11.2010, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.8.2010

Репутация: нет
Всего: нет



Ну это и ежу понятно, что для строковых параметров [b]int[] нах не нужен.
PM MAIL   Вверх
gcc
Дата 1.11.2010, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


Профиль
Группа: Участник
Сообщений: 2691
Регистрация: 25.4.2008
Где: %&й

Репутация: 2
Всего: 17



можно как тут:
http://forum.vingrad.ru/index.php?showtopi...t&p=2209139

Код

$_ =~ /^\d+$/ 


Код

$_ ^ $_


Это сообщение отредактировал(а) gcc - 1.11.2010, 23:35
PM WWW ICQ Skype GTalk Jabber   Вверх
noneg
Дата 21.1.2011, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 21.1.2011

Репутация: нет
Всего: нет



"Безопасное программирование на языке perl (Крис Касперски)"
книжка небольшая...интересно будем всем наверно почитать..
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl: CGI программирование"
korob2001
sharq
  • В этом разделе обсуждаются вопросы относящиеся только к CGI программированию
  • Если ваш вопрос не относится к системному или CGI программированию, задавайте его в общем разделе
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", качать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: разработка для Web | Следующая тема »


 




[ Время генерации скрипта: 0.1104 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.