ANTICHAT

ANTICHAT (https://forum.antichat.xyz/index.php)
-   PHP (https://forum.antichat.xyz/forumdisplay.php?f=37)
-   -   Статья про анти sql-inj (https://forum.antichat.xyz/showthread.php?t=30641)

nerezus 15.01.2007 11:07

На сервере он всегда по нулям ;)
А на девелоперской тачке по максимуму ;)

nerezus 02.01.2008 16:14

Обновил.

Meanor 08.01.2008 00:49

У меня в голове появилась кощунственная мысль засунуть кусочек кода в скрипт с библиотекой функций/классов чтобы он проводил через себя все 3 массива куков, пост и гет. С каждым элементом он производил определенные действия , а потом засовывал их обратно в массив.

Вопрос насколько это нужно и сильно ли это нагрузит все?

Macro 08.01.2008 00:51

Цитата:

Сообщение от Meanor
У меня в голове появилась кощунственная мысль засунуть кусочек кода в скрипт с библиотекой функций/классов чтобы он проводил через себя все 3 массива куков, пост и гет. С каждым элементом он производил определенные действия , а потом засовывал их обратно в массив.

Вопрос насколько это нужно и сильно ли это нагрузит все?

что-то типа foreach($_REQUEST as $key=>$value){}

nerezus 08.01.2008 00:57

Цитата:

Вопрос насколько это нужно и сильно ли это нагрузит все?
Это абсолютно не нужно. Второй вопрос тебя не должен волновать.

Meanor 08.01.2008 01:09

Цитата:

Сообщение от Macro
что-то типа foreach($_REQUEST as $key=>$value){}

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

nerezus 08.01.2008 01:18

Какой нафиг головной боли? Делай, как я написал, и ее не будет совсем. Нахрен тебе портить данные?

Isis 08.01.2008 03:59

Была бы статья о всех методах защиты....был бы большой плюс

FraiDex 02.02.2008 01:09

intro

В этой небольшой статье я расскажу о защите о всем нам известной уязвимости SQL-injection. Данной уязвимости подвержено подавляющее большинство сайтов в сети. Суть уязвимости заключается в отсутствии фильтрации спецсимволов в параметрах, передаваемых в запросах к БД. Уязвимость позволяет злоумышленнику выполнять запросы к БД… Да лан, чё я рассказываю. В разделе статьи полно информации по SQL-injection и я изобретать велосипед не буду.  Ну что ж, перейдём к сути…

Метод №1 – Фильтрация

Этот метод заключается в фильтрации спецсимволов с помощью стандартной функции preg_match(). Данная функция будет обрабатывать параметры, передаваемые скрипту от пользователя, на соответствие параметрам, которые должны быть в запросе. Вот кусок уязвимого скрипта:
PHP код:


    
if(!empty($_GET['id']))
    {
        
        
/*Получение нужной статьи из БД*/
            
        
$query "SELECT * FROM articles WHERE id = '$_GET[id]'";
        
$result_query mysql_query($query);
        if (!
$result_query) exit("Bad parametr");
        if (
$article mysql_fetch_array($result_query))
    {
… 

А вот тот же код, только с использованием функции preg_match():

PHP код:


    
if(!empty($_GET['id']))
    {
        
        
/*Проверка переданного параметра*/
        
        
if (preg_match("|^[\d]{1,3}$|"$_GET['id']))
        {
            
            
/*Получение из БД нужной статьи*/
            
            
$query "SELECT * FROM articles WHERE id = '$_GET[id]'";
            
$result_query mysql_query($query);
            if (!
$result_query) exit("Bad parametr");
            if (
$article mysql_fetch_array($result_query))
            {

else 
    {
        
        
/*Получение из БД всех статей*/
        
        
$query "SELECT * FROM articles";
        
$result_query mysql_query($query);
        if (!
$result_query) exit("Bad parametr");
        while (
$article mysql_fetch_array($result_query))
        {
… 

Согласитесь, не сложно написать пару лишних строк в скрипт, которые смогут защитить ваш сайт от атаки.
Некоторые перци обрабатывают параметр функцией mysql_escape_ptring(), она похожа на addslashes(). Лично я такой подход не уважаю. Этот способ можно использовать лиш как способ записи корректных SQL запросов и не более того. Многие используют фцнкцию str_replace() которая вырезает все спецсимволы в параметре. Но при использование данной функции запрос всё равно будет выполнен с ложными данными, и вызовет туеву хучу ошибок.

Способ №2 – создание собственной функции обращения к БД

Согласитесь, каждый раз добавлять preg_match достаточно нудное занятие, есть способ как этого избежать. Можно написать свою функцию , которая будет отправлять запросы к БД. Вот пример от Дмитрия Котерова, библиотека содержащая в себе функцию для защиты нашего скрипта. Суть её работы в том, что она заменяет стандартную и всем нам до боли известную функцию mysql_query() своей mysql_qw(), т.е. в либе он создал функцию, заменяющую mysql_query, в которую сразу встроена проверка спецсимволов, а так же HTML-тэгов. Данный скрипт защищает как от SQL-injection, так и от XSS. Вот код библиотеки:
PHP код:

<?php ## Простейшая функция для работы с placeholder-ами.

// result-set mysql_qw($connection_id, $query, $arg1, $arg2, ...)
//  - или -
// result-set mysql_qw($query, $arg1, $arg2, ...)
// Функция выполняет запрос к MySQL через соединение, заданное как
// $connection_id (если не указано, то через последнее открытое).
// Параметр $query может содержать подстановочные знаки ?,
// вместо которых будут подставлены соответствующие значения
// аргументов $arg1, $arg2 и т.д. (по порядку), экранированные и
// заключенные в апострофы.
function mysql_qw() {
  
// Получаем все аргументы функции.
  
$args func_get_args();
  
// Если первый параметр имеет тип "ресурс", то это ID соединения.
  
$conn null;
  if (
is_resource($args[0])) $conn array_shift($args);
  
// Формируем запрос по шаблону.
  
$query call_user_func_array("mysql_make_qw"$args);
  
// Вызываем SQL-функцию.
  
return $conn!==nullmysql_query($query$conn) : mysql_query($query);
}

// string mysql_make_qw($query, $arg1, $arg2, ...)
// Данная функция формирует SQL-запрос по шаблону $query, 
// содержащему placeholder-ы.
function mysql_make_qw() {
  
$args func_get_args();
  
// Получаем в $tmpl ССЫЛКУ на шаблон запроса.
  
$tmpl =& $args[0];
  
$tmpl str_replace("%""%%"$tmpl);
  
$tmpl str_replace("?""%s"$tmpl);
  
// После этого $args[0] также окажется измененным.
  // Теперь экранируем все аргументы, кроме первого.
  
foreach ($args as $i=>$v) {
    if (!
$i) continue;        // это шаблон
    
if (is_int($v)) continue; // целые числа не нужно экранировать
    
$args[$i] = "'".mysql_escape_string($v)."'";
  }
  
// На всякий случай запорняем 20 последних аргументов недопустимыми
  // значениями, чтобы в случае, если число "?" превышает количество
  // параметров, выдавалась ошибка SQL-запроса (поможет при отладке).
  
for ($i=$c=count($args)-1$i<$c+20$i++) 
    
$args[$i+1] = "UNKNOWN_PLACEHOLDER_$i";
  
// Формируем SQL-запрос.
  
return call_user_func_array("sprintf"$args);
}
?>

Используется он так
PHP код:

include_once( "./mysq_qw.php" );

    
if(!empty($_GET['id']))
    {
        
        
/*Получение нужной статьи из БД*/
            
        
$query "SELECT * FROM articles WHERE id = '$_GET[id]'";
        
$result_query mysql_qw($query);
        if (!
$result_query) exit("Bad parametr");
        if (
$article mysql_fetch_array($result_query))
    {
… 

Конечно он староват, но работает до сих пор…

Способ №3 – Использование mod_rewrite

Этот способ заключается в использовании модуля Апача под названием mod_rewrite. И так, как же мы его будем использовать??? :D Все знаю как данные передаются скрипту методом GET (www.site.ru/script.php?id=1), где id содержит параметры для обращения к БД. С использование mod_rewrite можно выше приведённой ссылке придать более человеческий вид (Например: www.site.ru/script_1.html). Для этого на нужно в веб-каталоге сервера (Например: /home/site/www) создать файл .htaccess со следующим кодом:
Код:

RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteRule ^.htaccess$ - [F]

Таким образом мы будем запускать модуль. Теперь перейдем к замене ссылок. Добавим в конец .htaccess следующую строку:
Код:

RewriteRule http://www.site.ru/script_([0-9]*).html http://www.site.ru/script.php?id=$1
Теперь при обращении к сайту www.site.ru/script_1.html произойдёт замена на http://www.site.ru/script.php?id=1, которая в последствии будет выполнена. “А в чём же здесь защита?” спросите вы. Обратите внимание на script_([0-9]*).html, здесь у нас идёт проверка переданных скрипту параметров, т.е. как мы видим: если передаваемый параметр будет содержать кроме числовых ещё какие-нибудь символы, то запрос выполнен не будет…
Дополнительную информацию о mod_rewrite и о его использовании можно найти в документации по серверу Apache. www.apache.org

Outro
Ну вот, я кратко описал способы решения данной проблемы. Если вам есть что добавить, просьба отписать в эту тему. Всем удачи.

DIAgen 02.02.2008 01:14

FraiDex
Цитата:

НИЧЕГО фильтровать не надо. СУБД - на то она и СУБД, а не херня какая-то, чтобы нормально любые данные принимать.

FraiDex 02.02.2008 01:17

фаг.. но ведь вё равно принимает. спецсимволы она не фильтрует

DIAgen 02.02.2008 01:31

Цитата:

Сообщение от FraiDex
фаг.. но ведь вё равно принимает. спецсимволы она не фильтрует

Цитата:

mysql_real_escape_string -- Экранирует специальные символы в строках для использования в выражениях SQL
Достаточно прогонять текстовые переменные по даной функции и больше не чего не надо
PHP код:

    function secure_sql($value) {
        if( 
get_magic_quotes_gpc()) {
            
$value stripslashes$value );
        }
        if( 
function_exists"mysql_real_escape_string" )) {
            
$value mysql_real_escape_string$value );
        } else {
            
$value addslashes$value );
        }
        return 
$value;
    } 


Isis 26.02.2008 03:17

Цитата:

Сообщение от DIAgen


Достаточно прогонять текстовые переменные по даной функции и больше не чего не надо
PHP код:

    function secure_sql($value) {
        if( 
get_magic_quotes_gpc()) {
            
$value stripslashes$value );
        }
        if( 
function_exists"mysql_real_escape_string" )) {
            
$value mysql_real_escape_string$value );
        } else {
            
$value addslashes$value );
        }
        return 
$value;
    } 


На вид большая функция а =\\

1) Зачем цифры переводить через эту функцию?
Достаточно
PHP код:

<?php
$xek 
intval($xek);
?>

2) Оох... где-то еще есть серваки с пхп 3 чтобы делать поверку на существование функции mysql_real_escape_string ?

3) mysql_real_escape_string не экранирует символы % и _ также как mysql_escape_string что будет багой например при %LIKE% .....
Поэтому достаточно написать свою функцию в 3 строки с реплейсом % и _ на \%, \_ ну и mysql_real_escape_string

neval 14.04.2008 22:58

Цитата:

Сообщение от Isis
На вид большая функция а =\\

1) Зачем цифры переводить через эту функцию?
Достаточно
PHP код:

<?php
$xek 
intval($xek);
?>



зри в корень )
Цитата:

Сообщение от DIAgen

Достаточно прогонять текстовые переменные по даной функции и больше не чего не надо

nerezus 02.10.2008 17:10

Могу скинуть свою обертку для запросов. Нужно?
На самом деле это боян, обертка типа.

PEHAT 16.11.2008 19:57

Цитата:

Сообщение от p-range
Код:

...
$val = (int)$_GET['val'];
$val = mysql_escape_string($val);
....


А зачем число ещё и mysql_escape_string'ом обрабатывать?

Krist_ALL 04.09.2009 20:19

Mysql_real_escape_string не спасет от слепых инекций.

.Slip 04.09.2009 20:21

Цитата:

Сообщение от Krist_ALL
Mysql_real_escape_string не спасет от слепых инекций.

А не от слепых спасает?:о

aleksej_sumarok 19.09.2009 13:39

Цитата:

Сообщение от nerezus
Могу скинуть свою обертку для запросов. Нужно?
На самом деле это боян, обертка типа.

Если не трудно скинь пожалуйста :)

Pashkela 27.09.2009 21:59

в топике ничего не упомянуто об:

1. реферере
2. сессии
3. прочие "особые" моменты

))

Практически никто этого не обрабатывает, если говорить про фул_паф_дискложен

nerezus 28.09.2009 00:58

Pashkela, ну я думал, что понятно, что нельзя доверять любому вводу )

Цитата:

Если не трудно скинь пожалуйста
Его уже не осталось, да и не нужен он - это было слабое подобие Zend_Db

m0Hze 28.09.2009 02:08

Цитата:

Сообщение от nerezus
Pashkela, ну я думал, что понятно, что нельзя доверять любому вводу )

Его уже не осталось, да и не нужен он - это было слабое подобие Zend_Db

Кстати,если уж дело зашло до Zend_Db, добавлю от себя отличный мануал по этой "обертке".
http://docs.huihoo.com/php/zend/ZendFramework-0.1.5/documentation/end-user/ru/zend.db.html
Читать очень легко,нет никаких супер-слов,все коды комментируються.В общем осваивайте,я сам остановился именно на Zend_Db.

nerezus 28.09.2009 07:27

Цитата:

Кстати,если уж дело зашло до Zend_Db, добавлю от себя отличный мануал по этой "обертке".
http://docs.huihoo.com/php/zend/ZendFramework-0.1.5/documentation/end-user/ru/zend.db.html
Чем же мануал по 0.1.5 версии актуальнее актуального 1.9.x на оффсайте?)))

m0Hze 28.09.2009 12:40

Цитата:

Сообщение от nerezus
Чем же мануал по 0.1.5 версии актуальнее актуального 1.9.x на оффсайте?)))

Тем,что он короче,и понятнее)
Хотя,кому как,лично мне в свое время было проще прочитать тот ман,чем офф :) Ибо много еще не понимал

Explоit 28.09.2009 12:43

Статья про анти sql-inj, а ачат - анти хак сайт,

а и ещё осталось не писать сплоиты, а исправлять баги веб приложений

Gray_Wolf 28.09.2009 13:02

Цитата:

Сообщение от Explоit
Статья про анти sql-inj, а ачат - анти хак сайт,

а и ещё осталось не писать сплоиты, а исправлять баги веб приложений

Вообщето ачат это сайт по аудиту безопасности.
Так что всё верно...

Forcer 23.10.2009 03:16

Ничего не сказано про prepared statement'ы. Именно из-за их использования ORM движки обладают побочным эффектом защиты от sql-inj.

nerezus 23.10.2009 10:20

Цитата:

Ничего не сказано про prepared statement'ы. Именно из-за их использования ORM движки обладают побочным эффектом защиты от sql-inj.
Ну это личные внутренности ОРМ, он может и по типу эскейпить просто. ;)
НО про них надо в другом месте сказать, обновлю )

Gray_Demon 12.11.2009 06:46

Уже на многих ру хостах юнион селект рубают , надежда ток на кавычку и знание движка(((

nerezus 12.11.2009 11:07

Цитата:

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

phpdreamer 18.12.2009 18:17

что думаете про такой подход?
PHP код:

function antihack () {  
  
$uri $_SERVER['REQUEST_URI']; //определяем адрес запрашиваемой страницы  
  
$arr_u explode("?"$uri ); //разделяем адрес на массив  
$url $arr_u[0];  //того что до знака ?   
$p_url $arr_u[1]; // и того что после  
  
  
$inj='/script|http|<|>|<|>|SELECT|UNION|UPDATE|AND|exe|exec|INSERT|tmp/i'//это паттерн возможных типов атак в адресе (их можно дополнить своими)  
  
  
if (preg_match($inj$p_url )) { // ищем патерн в нашем адресе, в том что за знаком ?  
  
    
die("Hacking attempt!"); //если находим - посылаем куда подальше :=)  
}  


взято с http://phpmaster.su/php-faq/8-kak-zashhititsya-ot-sql-inekcij-xss-atak-na-php.html
много чего можно добавить к этому коду, но сам подход..?

Qwazar 18.12.2009 18:23

phpdreamer, провальный подход. Первый пост читай, там ВСЁ описано.

Nightmarе 18.12.2009 18:27

Цитата:

Сообщение от phpdreamer
что думаете про такой подход?
взято с http://phpmaster.su/php-faq/8-kak-zashhititsya-ot-sql-inekcij-xss-atak-na-php.html
много чего можно добавить к этому коду, но сам подход..?

..с новым подходом....
Ты так никогда не защитишься. при SQL проскочит любой твой отфильтрованный контент в разном регистре UnIoN и т.д... буква i вообще может в переменной оказаться по делу, а фильтранётся =))) ну и про HEX, URL и другие виды кодировки не забывай =)))
А в первом посте всё изложенно.

phpdreamer 18.12.2009 18:37

спасибо, теперь разобрался

wolmer 18.12.2009 18:50

Цитата:

при SQL проскочит любой твой отфильтрованный контент в разном регистре UnIoN
Не соглашусь, сейчас пробывал в опере 10 набрать в get параметре это => "SeLEcT" (без ковычек), итог => не проскочило слово

Вообще да, плохая защита

cr0w 18.12.2009 19:17

Цитата:

Сообщение от phpdreamer
что думаете про такой подход?

Это ппц.
Засунуть в коммент в скл-инъекции знак "?" - вот и весь обход "фильтрации":
Код:

?lala=-1+/*?*/union+select+...
(;

Nightmarе

Буква "i" в той регулярке - модификатор...

phpdreamer 18.12.2009 20:05

Цитата:

Сообщение от cr0w
Это ппц.
Засунуть в коммент в скл-инъекции знак "?" - вот и весь обход "фильтрации":
Код:

?lala=-1+/*?*/union+select+...
(;

Nightmarе

Буква "i" в той регулярке - модификатор...

я тоже сразу подумал что надо проверять еще count массива... вопрос был не о том, но больше вопросов нет =)

imy681 19.12.2009 13:15

Скули обречены на вымирание :)
Юзайте mysqli и ничего фильтровать не надо и искейпить тоже не надо ничего.

$mysqli = new mysqli();
$mysqli->prepare("select * from data where id = ?");

и далее по тексту :)

Seravin 13.02.2010 05:03

А если так использовать можно избежать xss/sqli???
Код:

function secure($par) {
  $numb = array("1","2","3","4","5","6","7","8","9","0","-");
  if( get_magic_quotes_gpc())
          {
          $link = stripslashes($par);
          }
  $l=$par+1-1;
  if ((string)$l==(string)$par) {
         
    $par=(string)$par;
    $new_par="";
    for ($i=0;$i<>strlen($par);$i++) {
      if (in_array($par{$i},$numb)) {
      $new_par=$new_par.$par{$i};
          }
      if ($new_par<"-2147483648" || $new_par>"2147483647") $new_par="1";
        $new_par=(int)$new_par;
    }
  }
  else
  {
  $new_par=mysql_real_escape_string($par);
  }
  return $new_par;
}

Так вроде и раскрытия путей не будет

b3 13.02.2010 05:58

А где проверка на то что $par может быть массив?


Время: 07:55