|
|
|
| Здравствуйте. Прочитал несколько раз эту статью, и могу сказать, что она мне очень понравилась. Особенно хотелось бы отметить актуальность темы, рациональность построения, доступный и одновременно сжатый язык, несложные примеры, наличие ссылок на более подробные источники и ценные рекомендации в конце. Надо сказать, что какие-то методы защиты я уже использовал, с некоторыми только познакомился, а другие еще предстоит усвоить в дальнейшем. В любом случае данный материал может стать отправной точкой для еще более глубокого изучения проблемы безопасности. Могу сказать, что это не первый найденный мною материал по теме: некоторые статьи страдают отсутствием целостности, другие - ненаглядными и очень громоздкими примерами, третьи кишат орфографическими и грамматическими ошибками (хотя я и сам нередко допускаю пунктуационные ошибки (и не только :), поскольку имею дело с иностранными языками, и ни в каком из них нет таких жестких правил расстановки знаков препинания; к хорошему привыкаешь :). Эта статья лишена всех перечисленных выше недостатков, поэтому она стала первой статьей по теме безопасность, которую я оценил. Хочу выразить свою благодарность авторам статьи".
http://www.softtime.ru/info/articlephp.php?id_article=35
PS Не является ли очепяткой двойное echo в этой строке?
<input type=hidden name=session_id value=<?php <i>echo echo </i> session_id();?>> | |
|
|
|
|
автор: cheops (из ННГУ) (31.01.2005 в 17:14) |
|
|
для: antf
(31.01.2005 в 16:58)
| | Спасибо за добрый отзыв, опечатку сегодня же устраним. | |
|
|
|
|
|
|
|
для: cheops (из ННГУ)
(31.01.2005 в 17:14)
| | Еще вопросик насчет этой статьи.
Касаемо этого пункта:
<?php
// Устанавливаем соединение с базой данных
include "config.php";
// Осуществляем соответствия имени паролю
$query = "SELECT * FROM users
WHERE name = '$_POST[name]' AND
pass = '$_POST[pass]'";
$usr = mysql_query($query);
if(!$usr) exit("Ошибка в SQL-запросе");
if(mysql_num_rows($usr)>0)
{
// Вход в защищённую область сайта
}
?>
Ломается это таким методом:
123' AND 1=1
|
А если провести авторизацию так:
<?php
// Устанавливаем соединение с базой данных
include "config.php";
// Осуществляем соответствия имени паролю
$query = mysql_fetch_array(mysql_query("SELECT * FROM users
WHERE name = '$_POST[name]' AND
pass = '$_POST[pass]'"));
if ($_POST['pass'] == $query['pass'])
{
// Вход в защищённую область сайта
}
else exit();
?>
|
Тогда скрипт не уязвим подобной атаке? | |
|
|
|
|
|
|
|
для: Atom
(31.01.2005 в 18:51)
| | Да, и еще вариант
<?
$get = mysql_fetch_array(mysql_query("select login, password from users where login='$login'"));
if ($get['password'] == $password)
{
// Защищенная зона
}
else { exit(); }
?>
|
| |
|
|
|
|
|
|
|
для: Atom
(31.01.2005 в 18:58)
| | Нет такой способ не позволит обезопасить базу... лучше заменять прямые кавычки ' - обратными (не могу показать, так как на форуме это реализовано в движке :) - в общем она находится под буквой ё. | |
|
|
|
|
|
|
|
для: cheops
(31.01.2005 в 22:25)
| | Замена одинарных кавычек на обратные (как это реализовано в данном форуме) не является полноценной защитой от атак sql injection в случаях когда в php.ini отключены magic_quotes | |
|
|
|
|
|
|
|
для: 1dt.w0lf
(31.01.2005 в 22:53)
| | Хм... ну можно прибегать к явному экранированию кавычек... Кстати, почему, я что-то сообразить не могу если у нас в одинарные кавычки заключены обратные, как можно провернуть SQL-инъекцию? | |
|
|
|
|
|
|
|
для: cheops
(31.01.2005 в 23:04)
| | Вы имеете доступ к почте softtime@softtime.ru ? Просто туда я отправил описание некоторых ошибок. Если Вам интересно каким образом можно получить информацию из базы данных при таких условиях то можно пообщаться в аське. Стучите 100232001. | |
|
|
|
|
|
|
|
для: 1dt.w0lf
(31.01.2005 в 23:17)
| | Тоесть заменить кавычки и все? А что еще? Как польностью обезопасить базу?
И насчет magic quotes. Как узнать, включены они на хостинге или нет? | |
|
|
|
|
|
|
|
для: Atom
(31.01.2005 в 23:27)
| | Так как беседа с 1dt.w0lf прошла приватно, сухой остаток сообщу здесь. Узнать включены ли magic quotes можно при помощи функции get_magic_quotes_gpc(). В мануале предлагается следующее её использование
<?php
if (!get_magic_quotes_gpc()) {
$lastname = addslashes($_POST['lastname']);
} else {
$lastname = $_POST['lastname'];
}
?>
|
| |
|
|
|
|
|
|
|
для: cheops
(01.02.2005 в 00:27)
| | Тоесть если magic_quotes включены, то для безопасности надо только запросы в обратные кавычки помещать, а если выключенны, то addsleshes?
А что дает addslashes? | |
|
|
|
|
|
|
|
для: Atom
(01.02.2005 в 01:03)
| | Если magic_quotes включены как у нас на сайте, то все спец-символы экранируются автоматически, если это не так это нужно сделать самостоятельно при помощи функции addslashes() http://www.softtime.ru/dic/id_dic=12&id_group=1, а ещё лучше mysql_escape_string() http://www.softtime.ru/dic/id_dic=96&id_group=2
Кстати, вот несколько ссылок, которые рекомендуется почитать всем кто работает с MySQL (очень хорошее описание SQL-инъекций и методов защиты)
http://www.securitylab.ru/45438.html
http://www.securitylab.ru/49424.html
PS Эти ссылки добавлены в статью http://www.softtime.ru/info/articlephp.php?id_article=35 | |
|
|
|
|
|
|
|
для: cheops
(01.02.2005 в 02:39)
| | Я для авторизации использую следующий способ, подскажите чем он плох и как лучше сделать (если он не обеспечивает достаточной защиты):
<?
// $_SESSION['user_name'] - переменная в которой храниться имя пользователя
// если данный были введены в форму авторизации то они записываються
// в эту переменную. $_SESSION['user_pass'] - то же самое, только пароль.
//
$sql_name = $_SESSION['user_name'];
// (двух одинаковых имен пользователя в базе не существует)
$result = mysql_query ("SELECT pass FROM accbd WHERE set_user='$sql_name'");
$row = mysql_fetch_array ($result);
if ($row == NULL) {
// если пользователя с указанным именем нет в базе то не пускаем
} else {
// если пользователь найден в базе то проверяем далее:
$real_pass = $row["pass"];
// если пароль для указанного пользователя не верен то:
if ($real_pass != $_SESSION['user_pass']) {
// то не пускаем!
}
}
// если указанные имя и пароль оказались верны, то пускаем в закрытую часть
//
// занчения имя и пароль записываються шифрованными в сессию
// и в дальнейшем проверяються каждый раз как загружеться новая страница.
// В случае удачной проверки пользователь считаеться авторизованным.
?>
|
покритикуйте пжста! | |
|
|
|
|
|
|
|
для: localGhost
(01.02.2005 в 05:01)
| | Хм... скорее всего злоумышленник не будет пытаться сломать базу на этапе регистрации и постарается получить пароль к логину с универсальными правами... т.е. нужно смотреть регистрацию пользователей. | |
|
|
|
|
|
|
|
для: cheops
(01.02.2005 в 14:01)
| | А насчет универсальных прав.. Там таких нет =) Управление осуществляется через админку, защищенную htpasswd
Блин, я окончательно запутался.
У меня включены magic_quotes. При запросе я ставлю обр. кавычки, и нифига. С обычными работает скрипт, а с обратными нет. | |
|
|
|
|
|
|
|
для: Atom
(01.02.2005 в 14:24)
| | А куда вы ставите обратные кавычки? Здесь имеется ввиду замена прямых кавычек в тексте
на обратные перед помещением текста в базу данных | |
|
|
|
|
|
|
|
для: cheops
(01.02.2005 в 14:33)
| | Я совсем о другом думал.
Я переменную в запросе в кавычки помещал.
Так, оказывается на сервере magic_quotes выключен, значит addsleshes.
А эту функцию можно в самом запросе проверять?
Тоесть SELECT * from table where login='".addsleshes($login)."' ? | |
|
|
|
|
|
|
|
для: Atom
(01.02.2005 в 14:54)
| | Да эту функцию можно и так использовать. | |
|
|
|
|
|
|
|
для: 1dt.w0lf
(31.01.2005 в 23:17)
| | Спасибо за помощь, почту с softtime@softtime.ru обрабатываю не я, но все ваши письма будут обязательно мне переправлены. | |
|
|
|
|
|
|
|
для: Atom
(31.01.2005 в 18:58)
| | 2Atom
Все тоже самое. Тут еще надо смотреть конкретный случай. Если есть регистрация на сайте обычных пользователей, а по такому признаку приводиться авторизация админа, то можно войти по своим логином в админку... | |
|
|
|
|
|
|
|
для: Atom
(31.01.2005 в 18:51)
| | 2Atom
Тут есть свои тонкости. А что если я не укажу пароля вообще, а имя задам несуществующие? мы получим:
$_POST['pass'] = '';
$query['pass'] = '';
$_POST['pass'] == $query['pass'] | |
|
|
|
|
|
|
|
для: Artem S.
(01.02.2005 в 05:47)
| | . | |
|
|
|
|
|
|
|
для: Artem S.
(01.02.2005 в 05:47)
| | 2Artem S.
Если ты не укажешь пароля, то он не начнет выполнять скрипт. Я там не полностью расписал просто. Тоесть if (isset($_POST['login']) && isset($_POST['password'])) {
//authorise script
}
elseif(empty($_POST['login'] || empty($_POST['password']))
{
//input form
} | |
|
|
|
|
|
|
|
для: Atom
(01.02.2005 в 10:22)
| | ---
Если ты не укажешь пароля, то он не начнет выполнять скрипт. Я там не полностью расписал просто. Тоесть if (isset($_POST['login']) && isset($_POST['password'])) {
//authorise script
}
elseif(empty($_POST['login'] || empty($_POST['password']))
{
//input form
}
---
1. isset еще не означает что переменная не пуста, попробуй просто передать пустую переменную
2. зачем elseif? else вполне достаточно. | |
|
|
|
|
|
|
|
для: antf
(31.01.2005 в 16:58)
| | Не нужно все внимание обострять лишь на авторизации. Скорее всего, в скрипте будут и другие "дыры", через которые можно получить спец. права. Нужно смотреть весь код, и внимательно писать sql запрос и т.д.
Просто следуйте рекомендациям и проблем будит меньше. | |
|
|
|
|
|
|
|
для: Artem S.
(02.02.2005 в 07:09)
| | Я вот только не пойму зачем такое извращение? Зачем пытаться защититься от того, чего вообще не нужно допускать?
Я всегда при проверке пишу такой код:
$login=$_POST["snd_login"];
$pass=$_POST["snd_pass"];
$snd_hash=MD5($login . $pass);
$rez=mysql_query("SELECT usr_hash FROM Users WHERE usr_hash='" . $snd_hash . "');
|
И все. А при регистрации в базу пишу только пароль и хэш логин пароль. Можно и пароль не писать. но я всегда делаю сервис отправки забытого пароля, поэтому еще пароль храню, а логин вообще никуда не пишу, только хэш связки логин-пароль. | |
|
|
|
|
|
|
|
для: XPraptor
(02.02.2005 в 12:48)
| | 1. Скорость... все упирается в скорость работы. Твоя функция md5() будет заметно тормозить особенно при большом количестве юзеров.
2. А пароль то в базу записывается? Получается что его проверять все равно придется перед помещением в запрос при регистрации.
3. Одной авторизацией дело не ограничивается. Или ты все данные в базе шифровать собрался? | |
|
|
|
|
|
|
|
для: 1dt.w0lf
(02.02.2005 в 16:25)
| | На счет скорости ты зря! Шифр 24 букв абсолютно не занимает время.
Все данные шифровать не надо, я показал пример что нельзя сделать SQL инъекцию при таком методе проверке логина и пароля. И в других местах приема данных тоже надо сначала присвоить их переменным, потом если надо отфильтровать, а только потом подставлять в запрос. | |
|
|
|