Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   PHP, PERL, MySQL, JavaScript (https://forum.antichat.xyz/forumdisplay.php?f=37)
-   -   Защита от SQL-enjection (https://forum.antichat.xyz/showthread.php?t=30506)

je0n 03.01.2007 22:01

Защита от SQL-enjection
 
Короче нужна такая функция, которай я передаю переменную, а она ее обрабатывает и делает безопасной от XSS и SQL-enjection. Функция должна изменять переменную в своем теле (по ссылке), и если переменная была опасна вернуть TRUE иначе FALSE.
Вот что получилось у меня:
Код:

<?php
function filter(&$value)
{
  $b=FALSE;
  if(strpos($value,"'"))
  {
    $value=str_replace("'","",$value);
    $b=TRUE;
  }
  if(strpos($value,";"))
  {
    $value=str_replace(";","",$value);
    $b=TRUE;
  }
  if(strpos($value,"/"))
  {
    $value=str_replace("/","",$value);
    $b=TRUE;
  }
  if(strpos($value,"<"))
  {
    $value=str_replace("<","",$value);
    $b=TRUE;
  }
  if(strpos($value,">"))
  {
    $value=str_replace(">","",$value);
    $b=TRUE;
  }
  return $b;
}
?>

Ну а юзать эту функцию премерно вот так:
Код:

$name=$_POST["name"];
if(filter($name))
{echo "you cant use symbols ',/ here";exit;}

Тока не говорите нафига изменять переменную, если все равно выхожу из скрипта (exit; ). Это на тот случай если выходить не прийдеться, а еще и юзать дальше эту переменную. Ведь я не знаю как дальше будет развиваться все остальное, ради чего я и пишу этот скрипт.
Я фигово разбираюсь во всех атаках, поэтому прошу добавить/исправить код, чтобы он был неуязвим )) даже в том случае, если эту переменну прийдеться использовать дальше как в БД, так и выводить в страницу.

Termin@L 03.01.2007 22:31

ИМХО Проще не замарачиваться, а пользоваться функциями ereg() и htmlspecialchars(), проще явно указать - что можно, а не то что нельзя использовать, а в твоём случае пройдёт такой запрос -
Код:

union select 1,2,3,4,5#
от xss тоже не спасёт, лишь осложнит задачу немного.
Код:

if(!ereg("[A-Za-z]{1,8}",$name)
return false;


max_pain89 03.01.2007 22:44

да сопри из любого форума или КМС, так есть такие функции, просто иногда забывают их применять к переменным

je0n 03.01.2007 22:47

спасибо, решил использовать вместо strpos функцию ereg, а вместо str_replace ereg_replace. Тока недоганю как составить правильный шаблон для функций ereg. Помогите плз, чтобы он пропул русские, английские буквы, точку, запятую и цифры. Как должен выглядеть шаблон

Цитата:

да сопри из любого форума или КМС, так есть такие функции, просто иногда забывают их применять к переменным
Меньше всего хочеться копаться в исходниках форума ;). Я уже думал об этом. Кроме того, вряд ли там все ограничивается одной функцией )

gemaglabin 03.01.2007 22:51

Simple Machine Forums

Код:

function db_query($db_string, $file, $line)
{
        global $db_cache, $db_count, $db_connection, $db_show_debug, $modSettings;

        // One more query....
        $db_count = !isset($db_count) ? 1 : $db_count + 1;

        // Debugging.
        if (isset($db_show_debug) && $db_show_debug === true)
        {
                // Initialize $db_cache if not already initialized.
                if (!isset($db_cache))
                        $db_cache = array();

                if (!empty($_SESSION['debug_redirect']))
                {
                        $db_cache = array_merge($_SESSION['debug_redirect'], $db_cache);
                        $db_count = count($db_cache) + 1;
                        $_SESSION['debug_redirect'] = array();
                }

                $db_cache[$db_count]['q'] = $db_string;
                $db_cache[$db_count]['f'] = $file;
                $db_cache[$db_count]['l'] = $line;
                $st = microtime();
        }

        // First, we clean strings out of the query, reduce whitespace, lowercase, and trim - so we can check it over.
        if (empty($modSettings['disableQueryCheck']))
        {
                $clean = '';
                $old_pos = 0;
                $pos = -1;
                while (true)
                {
                        $pos = strpos($db_string, '\'', $pos + 1);
                        if ($pos === false)
                                break;
                        $clean .= substr($db_string, $old_pos, $pos - $old_pos);

                        while (true)
                        {
                                $pos1 = strpos($db_string, '\'', $pos + 1);
                                $pos2 = strpos($db_string, '\\', $pos + 1);
                                if ($pos1 === false)
                                        break;
                                elseif ($pos2 == false || $pos2 > $pos1)
                                {
                                        $pos = $pos1;
                                        break;
                                }

                                $pos = $pos2 + 1;
                        }
                        $clean .= '%s';

                        $old_pos = $pos + 1;
                }
                $clean .= substr($db_string, $old_pos);
                $clean = trim(strtolower(preg_replace(array('~\s+~s', '~/\*!40001 SQL_NO_CACHE \*/~', '~/\*!40000 USE INDEX \([A-Za-z\_]+?\) \*/~'), array(' ', '', ''), $clean)));

                // We don't use UNION in SMF, at least so far.  But it's useful for injections.
                if (strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0)
                        $fail = true;
                // Comments?  We don't use comments in our queries, we leave 'em outside!
                elseif (strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, ';') !== false)
                        $fail = true;
                // Trying to change passwords, slow us down, or something?
                elseif (strpos($clean, 'set password') !== false && preg_match('~(^|[^a-z])set password($|[^[a-z])~s', $clean) != 0)
                        $fail = true;
                elseif (strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0)
                        $fail = true;
                // Sub selects?  We don't use those either.
                elseif (preg_match('~\([^)]*?select~s', $clean) != 0)
                        $fail = true;

                if (!empty($fail))
                {
                        log_error('Hacking attempt...' . "\n" . $db_string, $file, $line);
                        fatal_error('Hacking attempt...', false);
                }
        }

        $ret = mysql_query($db_string, $db_connection);
        if ($ret === false && $file !== false)
                $ret = db_error($db_string, $file, $line);

        // Debugging.
        if (isset($db_show_debug) && $db_show_debug === true)
                $db_cache[$db_count]['t'] = array_sum(explode(' ', microtime())) - array_sum(explode(' ', $st));

        return $ret;
}


Termin@L 03.01.2007 22:55

Код:

if(!ereg("[А-Яа-яa-zA-Z0-9]{1,8}",$_POST['post'])){echo "Error";exit;}
примерно так

je0n 03.01.2007 22:56

2Гема
и что это?
Эта функция очень далека от того, что надо мне?

je0n 03.01.2007 22:58

Цитата:

if(!ereg("[А-Яа-яa-zA-Z0-9]{1,8}",$_POST['post'])){echo "Error";exit;}
а точка, запятая, дефис,ничжнее подчеркивание (ну и все нормальные символы, включены сюда?

Termin@L 03.01.2007 23:01

Нет тут, только - точка, запятая, кавычка, всё остальное добавляешь в квадратные скобки подряд, только дефис нужно обязательно в конец.
P.s. пробел тоже надо вставлять
сори не ту строку те кинул вот -
if(!ereg("[А-Яа-яa-zA-Z0-9',.; -]{1,8}",$_POST['post'])){echo "Error";exit;}

DIAgen 03.01.2007 23:04

Цитата:

Сообщение от je0n
а точка, запятая, дефис,ничжнее подчеркивание (ну и все нормальные символы, включены сюда?

Зачем изобретать велосипед, возми DLE 5.2 там все хорошо сделано с точки безопасносит и грамотно написано


Время: 18:22