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

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   PHP, PERL, MySQL, JavaScript (https://forum.antichat.xyz/forumdisplay.php?f=37)
-   -   Статья про анти sql-inj (https://forum.antichat.xyz/showthread.php?t=30641)

nerezus 05.01.2007 20:01

Статья про защиту от SQL-inj
 
Статья про защиту от SQL-inj

Что такое SQL-inj?
Сам знаешь. Иначе бы не читал. Так что сиди и читай дальше ;)

Как проводятся SQL-inj?
Вбивай в гугл и ищи статьи всяких разных хакеров. Если искать не умеешь - то дальше не читай, все равно не поймешь.

Как защититься?
Что, нагуглил статей? Может и про защиту написано?
Какие-нибудь леменги вроде Михуила Фленова. фильтровать советуют? Шли нах.
Ничего, повторяю еще раз для альтернативно-одаренных: НИЧЕГО фильтровать не надо. СУБД - на то она и СУБД, а не херня какая-то, чтобы нормально любые данные принимать.
Наша задача - просто правильно эти данные преподнести.
Защищаться надо так(применительно к PHP и mysql):
1) Если поле в базе числовое, то: (int) (ну или intval()). Можно по модулю взять при использовании в LIMIT, но это не секурити-дырка.
2) Если текстовое, то просто mysql_real_escape_string()
3) Всякие magic quotes и подобные затычки отключены. Кто не отключил - ССЗБ(что это означает - смотрите на LOR'е)
И ВСЕ! Больше ничего не надо. Ибо запрос испортить левыми данными нельзя.
Повторю еще раз: НИКАКИХ ФИЛЬТРАЦИЙ.
LIKE/RLIKE/AGAINST/etc - это частный случай, и рассматривается отдельно.
Примера не будет. Если не понял - значит это тебе не надо.

ORM
Что это такое, написано здесь: http://ru.wikipedia.org/wiki/ORM
Защита от SQL-inj - это побочный результат применения данной технологии.

Что касательно защиты от XSS, то никаким образом к БД это не относится.
Так что те, кто хотел это все объединить в 1 функцию(да к тому же и с проверкой) - идите лесом. Это кардинально разные вещи и они друг к другу не относятся.

И да пребудет с вами сила(не со всеми)!

nerezus, 5.01.07-2.01.08

max_pain89 05.01.2007 20:22

хм довольно странный, даже не статья, а пост.

В защиту magic quotes скажу что если ставишь двиг, не собственно ручно написаный, смысла отключать не вижу, больше риск.

nerezus 05.01.2007 21:06

Я сначала хотел что-то из строчек восьми написать )
Но написал больше.
Причина - тема http://forum.antichat.ru/thread30506.html

Ну а чтьо касается magic quotes - то нефиг юзать кривые движки ;)

blaga 05.01.2007 21:28

intval() например при -12 выводит -12. Это не дырка? А вот насчет mysql_real_escape_string() это ты в точку! Нхрена писать невпупенные функции когда можно одной строчкой обойтись.

nerezus 05.01.2007 21:39

Цитата:

intval() например при -12 выводит -12. Это не дырка?
Я даже приписал:
"Можно по модулю взять в LIMIT, но это не секурити-дырка."

blaga 05.01.2007 21:40

Извини, пойду лучше учебник по скулю почитаю.

_Great_ 05.01.2007 21:49

Цитата:

intval() например при -12 выводит -12. Это не дырка?
не-а =)

Zadoxlik 05.01.2007 22:10

Это все ясно, только ты не раскрыл тему=) Например при Selectе с Like надо экранировать еще пару символов, хотя логика очень здравая и самому ни раз мысль такая приходила при прочтении описаний разного рода фильтраций =)

guest3297 06.01.2007 00:15

А если админы эту статью прочитают ведь все sql иньекции закроют?
Статью в приват!

blaga 06.01.2007 06:44

2[ cash ], тебя как самого умного в подполье работать на сопротивление.

Xex 09.01.2007 04:50

Цитата:

Сообщение от Zadoxlik
Это все ясно, только ты не раскрыл тему=)

Согласен,
забыли про грамотное распределение прав в СУБД.

nerezus 09.01.2007 10:27

вы еще про хранимые функции скажите =)))

Dracula4ever 09.01.2007 10:49

Чтобы защитится от SQL Injection надо, прежде всего надо распределять по его видам.
К примеру, если мы хотим получить целое число (int) надо чтобы шла проверка что это число и правда целое.
Это можно осуществить с помощью функнии IsNumeric в таком виде:
Цитата:

If (not IsNumeric(Request("ID"))) then ...
Так же надо чтобы не показывались ошибки, которые приводят к взлому сайта.
Есть полно путей сделать это, но помойму лучше всего это осуществить с помощью того, что есть ошибка работа не прекратилась.
Цитата:

номер ошибки error resume next

nerezus 09.01.2007 14:09

Цитата:

надо чтобы шла проверка что это число и правда целое
Во-первых, никаких проверок не надо! Сколько раз повторять?
Во-вторых, int не может быть не целым!

k1b0rg 09.01.2007 14:56

error_reporing(0);
magic_quotes on

и числа передаваемые базе тоже обрамляем ковычками типо
Цитата:

.. where id ='1'

и хакеры прутся полем

GHostly_FOX 10.01.2007 07:44

Мой метод защиты:

Если вы передаете только текст и числа в скрипты к примеру:
index.php?modules=news&id=1
то вполне подойдет данный код:

PHP код:

function var_chek($var,$col){
    
$var    =    substr($var0$col);
    
$var    =    preg_replace("/[^\w\x7F-\xFF\s]/"""$var);
    
$good    =    ereg_replace(" +"" "$var);
    
$good    =    strip_tags($good);
    return 
$good;
}

$modules=var_chek($modules,10);
$id=var_chek($id,5); 

Данный код не только удалит все спец символы из передаваемых строк но и обрезает по длинне, ни один XSS или SQL inj... не пройдет через этот фильтр.

nerezus 10.01.2007 08:04

Цитата:

GHostly_FOX
Воот... прекрысный пример в тему как не надо делать...

k1b0rg 10.01.2007 10:38

Примерно такой же код используется в последних версиях phpbb

_Great_ 10.01.2007 11:47

так действительно делать не надо.
Лучшим средством будет типизирование параметров - явно прописать в скрипте имена параметров и их типы и соответствующе их парсить. Если int - делать intval(), если string - делать mysql_escape_string.
При выводе всех значений на экран обрамлять в htmlspecialchars, а резать это при передаче в БД - маразм.
Тут я на 100% согласен с nerezus'ом

nerezus 10.01.2007 15:00

Цитата:

magic_quotes on
Обязательно off.
Т.к. иначе будет двойное экранирование.

И вообще magic_quotes, register_globals и т.д. отменили в PHP6, чтобы криворукие недокодеры не юзали их )

Цитата:

и числа передаваемые базе тоже обрамляем ковычками типо
Зачем?

k1b0rg 10.01.2007 17:44

чтобы нельзя было провести инъекцию......из под ковычек не выйти

nerezus 10.01.2007 18:13

Цитата:

чтобы нельзя было провести инъекцию
А разве без этой штуки можно? подумай хорошенько )

k1b0rg 10.01.2007 18:42

я не про твой способ говорил а про свой, где я указал что простого magic quotes on будет достаточно с обрамленныеми параметрами. Если числа не обрамлять, тогда инъекция возможна.

nerezus 10.01.2007 18:53

Цитата:

простого magic quotes on будет достаточно
а если тебе попадется нормально настроенный хостинг? или с новой версией пхп(в ближайшем будущем)?

Что, переписывать будешь?

k1b0rg 10.01.2007 19:29

Цитата:

а если тебе попадется нормально настроенный хостинг?
ini_set();

Цитата:

или с новой версией пхп(в ближайшем будущем)?
Я сомневаюсь, что это будет в ближайшем. Ну 2-3 хостера поставят новую версию, остальные врядли.

Цитата:

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

Zadoxlik 10.01.2007 19:35

С каждым нерезусовым словом в топе согласен :d

nerezus 10.01.2007 21:15

k1b0rg, воот: у тебя каждое неправильное решение/костыль тащит за собой еше гору костылей, и они нарастают как снежный ком.

А теперь посмотри на альтернативу(которая, кстати легче): писать правильно.

GHostly_FOX 12.01.2007 10:11

Цитата:

Сообщение от nerezus
Воот... прекрысный пример в тему как не надо делать...

Почему же нет?!
Данный код позволяет мне получать чистые данные, на моем сайте в основном передаются только числа и текст... все остальное лишнее и я это убираю...

blaga 12.01.2007 10:26

потому что вместо 10 строчек можно обойтись одной.

nerezus 12.01.2007 11:01

blaga. Нет не по этому. У него совсем неправильно.

GHostly_FOX, данные у тебя не "чистые", как ты выразился, а испорченные. Теряем информацию при твоей "обработке".

k1b0rg 12.01.2007 11:37

int и intval() ограничены -2147483648 до 2147483648

а числа большие этому, предлагаешь уже строкой брать? тогда ты пролетишь mysql_real_escape_string тебе не поможет, взломают так что ноги согнутся...




$id=is_numeric($_GET['id'])?$_GET['id']:0;

тебя опять эта запись не устроит? )) is_numeric возьмет любое число)

nerezus 12.01.2007 11:55

k1b0rg, спасибо, посмеялся.

А теперь немного подумай. Головой.
Предположим, в движке обрабатываем ее как:
1) ...как строку. Тогда причем int/intval() ?
2) ...как число. Тогда туда и не должны попасть такие значения, а int/intval() обрежет только неправильные.

nc.STRIEM 14.01.2007 01:29

nerezus молодца! реальн клево отписал! я даж посмеялся! хоть не впадлу читать было, т.к. не много)))

а ваше я обычно все параметры передоваемые в запрос беру в ' ' а в самих параметрах экранирую ' и всегото!))

_Great_ 14.01.2007 01:40

Цитата:

а ваше я обычно все параметры передоваемые в запрос беру в ' ' а в самих параметрах экранирую ' и всегото!))
ну дык так и надо делать правильно.
mysql_escape_string поможет правильно передать любую строку в базу данных, а intval поможет передать число

nc.STRIEM 14.01.2007 01:50

а не прощи ли сделать
PHP код:

 $str=str_replace("'","\'",$str); 


nerezus 14.01.2007 11:51

Конечно нет.
запрос можно испортить.
А эта функция экранирует еще и другие символы.

p-range 14.01.2007 19:32

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

вот пример безопасного кода:
Код:

<?php
$val = (int)$_GET['val'];
$val = mysql_escape_string($val);
$q = mysql_query("SELECT id,name,etc FROM table WHERE val = '$val'");
if (!$q)
{
        echo '<br>Неверное значение переменной $val';
}
        else
{
while ($a = mysql_fetch_array($q))
{
        $id = $a['id'];
        $name = $a['name'];
        $etc = $a['etc'];
        $name = htmlspecialchars($name);
        $etc = htmlspecialchars($etc);
        // вывод результата
}
}
?>

вот.

nerezus 14.01.2007 23:27

Почти верно.
Почему почти?
$val = isset($_GET['val']) ? (int)$_GET['val'] : 0;

ZaCo 15.01.2007 00:16

от инекции да. все верно.
>>но это не секурити-дырка.
бебе от инекции да, но секурити;) тк можно получить раскрытие пути. чем не бага.

_Great_ 15.01.2007 10:20

ZaCo, а если у меня еррор_репортенг по нулям? :)


Время: 00:14