|
|
|
| Есть точка зрения на обеспечение безопасности php-скриптов при работе с БД.
Обычно попытки поломать базу производятся через внедрение несанкционированных кодов в тело запроса mysql_query с целью заставить скрипт выполнить действия, не предусмотренные разработчиком скрипта.
Т.е. модифицируется запрос.
А если организовать получение данных из БД таким образом:
Запрос всегда имеет вид SELECT A, B, C FROM `tblName`. Результат запроса фильтруется на предмет соответствия с необходимыми параметрами.
Пример из хэлпа:
а) Стандартный запрос:
<?php
$offset = argv[0]; // проверка пользовательских данных отсутствует
$query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
$result = mysql_query($query);
?>
|
Если $offset равен
0; UPDATE user SET Password=PASSWORD('crack') WHERE user='root'; FLUSH PRIVILEGES;
база данных передана в полное распоряжение постороннего человека. Конечно есть is_numeric(), strip_tags() и т.д.
Но новые дыры в безопасности отыскиваются постоянно. Да и в более сложных случаях, чем в этом примере, можно что-то упустить из поля зрения.
Т.е. потенциально опасность существует всегда.
б) "вид сбоку":
<?
$query = "SELECT id, name FROM products ORDER BY name";
$result = mysql_query($query);
for ($i = $offset; $i < $offset + 20; $i++;){
//любым удобным способом выделить 20 элементов из результата в отдельный массив
//если $offset некорректен, просто произойдет ошибка цикла for.
}
?>
|
В этом варианте несущая угрозу переменная $offset в запросе не участвует и никакого влияния на БД оказать не может.
В php достаточно средств для реализации таких вещей, как WHERE, ORDER BY, OFFSET, LIMIT, которые участвуют в подавляющем большинстве запросов.
И можно полностью изолировать БД от возможного вредоносного влияния параметров, передаваемых в скрипт.
Естественно, код будет выглядеть несколько непривычно, возможно не совсем оптимально, но зато БД совершенно неподвержена взлому с его использованием.
К тому же при работе с удаленными серверами непринципиально, сколько надо ждать результата: 0,01 сек или 0,1 сек или 1 сек.
Есть какие соображения по данному способу обеспечения безопасности? | |
|
|
|
|
|
|
|
для: Хулиган
(08.02.2008 в 21:14)
| | Соображения:
1. Не изобретайте велосипед;
2. Проверяйте все переданные от пользователя данные
3. Если априори известно, что в переменной должно быть число — ctype_digit()
3. ...если строка — mysql_escape_string() | |
|
|
|
|
|
|
|
для: Саня
(08.02.2008 в 23:47)
| | То есть Вы считаете, что нужно дать потенциальному взломщику возможность составлять запросы?
И при этом уповать, что разработчики предусмотрели защиту от всех уязвимостей? Наивно надеяться на это :)
Несмотря на то, что дыры постоянно латаются, появляются новые дыры, причём с завидной регулярностью :)))
Завтра/послезавтра/через год может появится новая дыра, от которой не спасут ни mysql_escape_string, ни ctype_digit...
Можете не сомневаться.
То, что я предлагаю, абсолютно изолирует потенциально вредоносный код от общения с базой данных.
Вместо того, чтобы пустить козла в огород, и следить за ним, чтобы не сожрал чего лишнего, проще (и разумнее) козла в огород не пущать вообще.
Тогда и следить не надо. | |
|
|
|
|
|
|
|
для: Хулиган
(09.02.2008 в 01:17)
| | Похоже,вы просто мало знакомы с работой с БД.Если убрать все,что вы предлагаете,то база нахрен не нужна и все можно реализовывать в файловой системе.Наоборот,при правильной реализации хватит escape_string и проверки числовых данных. | |
|
|
|
|
|
|
|
для: Ralph
(09.02.2008 в 01:44)
| | Скажу так: eval($_POST['code']) может создать огромную проблему безопасности,так может от php откажемся ? В любом случае,это проблема не языка,а прямизны рук | |
|
|
|
|
|
|
|
для: Ralph
(09.02.2008 в 01:44)
| | . | |
|
|
|
|
|
|
|
для: Хулиган
(09.02.2008 в 01:17)
| | Почитайте статей на тему SQL инъекций.. Вы похоже смысла не уловили... | |
|
|
|
|
|
|
|
для: kasmanaft
(09.02.2008 в 07:09)
| | Кстати,автор глубоко ошибается,говоря "каждый год появляются новые дыры в безопасности"...Ничего нового не придумывается,все время наступают на те же самые грабли.И когда таблица вырастет к примеру до 300.000 строк,и для получения одной строки придется тащить всю таблицу,а таких запросов в скрипте может быть 5-10-... ,то какие там нафиг 0.1-1 сек :-) | |
|
|
|
|
|
|
|
для: Ralph
(09.02.2008 в 08:43)
| | Если убрать все,что вы предлагаете,то база нахрен не нужна и все можно реализовывать в файловой системе.
Файловая система никак не заменит БД, даже на самых простых запросах. Хотя бы с точки зрения одновременного доступа.
Наоборот,при правильной реализации хватит escape_string и проверки числовых данных.
Кстати,автор глубоко ошибается,говоря "каждый год появляются новые дыры в безопасности"...Ничего нового не придумывается,все время наступают на те же самые грабли.
Я вот думаю, если всё так просто, всего лишь одна-единственная уязвимость, и все регулярно на неё попадаются, почему не реализованы какие-либо механизмы контроля и предотвращения таких случаев на уровне ядра php или mysql? Разве это невозможно? Например контролировать типы переменных и блокировать запросы, если типы переменных не совпадают с типами полей. Или блокировать возможность упаковки в один запрос двух независимых запросов (как в приведенном выше примере).
В любом случае,это проблема не языка,а прямизны рук
Безусловно, проблема кривизны рук присутствует, но и проблема языка тоже имеет место быть.
Попробуйте скомпилировать компилятором си что-нибудь такое:
void foo (int param){
//
}
foo ("string");
реакцию си-компилятора предугадать несложно. Строгая типизация не позволит скомпилировать ошибочный код.
А для php/mysql такого рода вещи проходят на ура. А вы говорите, что это не проблема языка...
P.S.
Я использую традиционное построение запросов, и отказываться от него в пользу самодельной реализации запросов не собираюсь. Просто интересно было потеоретизировать на тему. Но что-то вся дискуссия свелась к тому, что я "сам криворукий дурак". | |
|
|
|
|
|
|
|
для: Хулиган
(09.02.2008 в 17:22)
| | > for ($i = $offset; $i < $offset + 20; $i++;)
Знаете, в математике есть такое свойство у неравенств: если a < b, то для любого c a + c < b + c. Математически значение $offset тогда не играет нихрена. Всегда будет 20 итераций (но в некоторых языках программирования типа C может быть при подобном коде меньше итераций).
> Завтра/послезавтра/через год может появится новая дыра, от которой не спасут ни mysql_escape_string, ни ctype_digit...
> Можете не сомневаться.
Программа - не забор. Если сегодня 0 == 0, то и завтра будет то же самое. | |
|
|
|
|
|
|
|
для: Unkind
(09.02.2008 в 17:45)
| | Всегда будет 20 итераций (но в некоторых языках программирования типа C может быть при подобном коде меньше итераций).
Здесь не конкретная реализация на конкретном языке программирования. Это "цикл по выборке 20-ти индексов, удовлетворяющих некоторым условиям".
Программа - не забор. Если сегодня 0 == 0, то и завтра будет то же самое.
То есть вы хотите сказать, что после обнаружения в "заборе" (ПО) дыры, и изготовления заплатки на неё (сервиспак), больше дыр нет???? В таком случае объясните мне, откуда берутся SP1, SP2, SP3, SP4 и т.д.?
А ведь программа по прежнему программа, что сегодня, что завтра...
После каждой очередной заплатки вы думаете, что закрыли все дыры, а они всё появляются и появляются... | |
|
|
|
|
|
|
|
для: Хулиган
(09.02.2008 в 20:20)
| | > Здесь не конкретная реализация на конкретном языке программирования
Так приведите конкретный пример, который наглядно отражает Вашу идею. Вы привели пример без какого-либо смысла. Отсюда я не могу понять, что в нём полезного.
> То есть вы хотите сказать, что после обнаружения в "заборе" (ПО) дыры, и изготовления заплатки на неё (сервиспак), больше дыр нет?
Ну у Вас и логика. С чего Вы это взяли? | |
|
|
|
|
|
|
|
для: Хулиган
(08.02.2008 в 21:14)
| | >К тому же при работе с удаленными серверами непринципиально, сколько надо ждать результата: 0,01 сек или 0,1 сек или 1 сек.
Представьте страничку форума. Не этого, аскетичного, а полноценного - с аватарками, с рангами, репутацией, подписями и еще миллионом всяких фенечек. Для ее генерации делается добрая сотня запросов к БД, причем половина из них - это перекапывание огромных таблиц. Если все их делать так, как вы предлагаете, сервер просто ляжет=) РНР по определению медленнее MySQL, и с этим ничего не поделать.
Да и потом, существует понятие php-injection, там БД вообще ни при чем. Так что абсолютной зашиты не бывает) | |
|
|
|
|