|
|
|
| Всем привет. Cheops и уважаемые гости форума!
Оцените скрипт авторизации на сессии.
Выскажите свое мнение в плане безопасности и других недоработок.
form.php
//вызов подключаемого модуля, отвечающего за вывод формы и авторизации
<?php
session_start();
if(!defined("MAIN")) return;
/*if ($_POST['session_id'] != session_id())
{
$error[] = "Попытка передачи данных с другого хоста. Скрипт остановлен.";
} */
if (isset($_POST['sub']))
{
$title_html = "Вход в систему";
///////////////////////////////////////////////////////////
// Блок подготовки и проверки
///////////////////////////////////////////////////////////
// Получаем данные отправленные методом POST
$name = trim($_POST['name']);
$pass = trim($_POST['pass']);
// Проверяем правильность ввода данных
if(empty($name) or empty($pass)) $error[] = "Ошибка: Вы не указали логин или пароль.";
if(empty($error))
{
// Подготавливаем переменные для добавления в SQL-запрос, экранируя
// все спецсимволы при помощи функции mysql_escape_string();
if (!get_magic_quotes_gpc())
{
$name = mysql_escape_string($name);
$pass = mysql_escape_string($pass);
}
// заменяем все специальные символы эквивалентом
$name = htmlspecialchars(substr($name,0,7));
$pass = htmlspecialchars(substr($pass,0,7));
$query = "SELECT name,pass FROM users
WHERE name = '$name'";
list($m_name, $m_pass) = mysql_fetch_row(mysql_query($query));
if ($m_pass != md5($pass) or // даст TRUE, если пароли не равны
$name != $m_name)
$error[] = "Ошибка: Неверный логин или пароль.";
else
{
$_SESSION['authorized'] = true;
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['name'] = $name;
}
}
}
if (isset($_POST['out']))
{
// Уничтожить все переменные в сессии
$_SESSION = array();
// destroy the session
session_destroy();
// redirect to login page
echo "<HTML><HEAD>
<META HTTP-EQUIV='Refresh' CONTENT='0; URL=main.php'>
</HEAD></HTML>";
}
?>
<form method="post" title="Вход для пользователей">
<input name=session_id type="hidden" value=<?php echo session_id();?>>
<table cellspacing="0" border="0" cellpadding="0" class="login">
<tr>
<td colspan="4"><div id="text2">Имя пользователя:</b></div></div></td>
</tr>
<tr>
<td><img src="dataimg/input100.gif" width="6" height="20" border="0" alt=""></td>
<td><input type="text" name="name" title="Введите логин" class="login" align="middle" value='<?= $_SESSION['name'];?>' maxlength="8"></td>
<td><img src="dataimg/input200.gif" width="6" height="20" border="0" alt=""></td>
<td width="37"> </td>
</tr>
<tr>
<td colspan="4"><div id="text2">Пароль:</b></div></div></td>
</tr>
<tr>
<td><img src="dataimg/input100.gif" width="6" height="20" border="0" alt=""></td>
<td><input type="password" name="pass" title="Введите пароль" align="middle" class="login" maxlength="8"></td>
<td><img src="dataimg/input200.gif" width="6" height="20" border="0" alt=""></td>
<td valign="top"><!--<INPUT type="image" src="dataimg/but-ente.gif" align="middle" class="button">--></td>
</tr>
<tr>
<td></td>
<td align="center">
<?php
if (isset($_SESSION['name'])) echo "<input type=submit name=out value=Выйти class=button></td>";
else echo "<input type=submit name=sub value=Войти class=button></td>";
?>
<!--<input type="submit" name="sub" value="Войти" class="button"> </td>-->
<td></td>
<td width="37"> </td>
</tr>
</table>
</form>
|
main.php
Для доступа к закрытой части в главном модуле, используем:
if (!empty($_SESSION['authorized']) &&
$_SESSION['ip'] == $_SERVER['REMOTE_ADDR'])
echo "Привет".$_SESSION['name'];
|
| |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 08:59)
| | В чистом виде ошибка
$pass = mysql_escape_string($pass);
|
Тоже не лучше
$pass = htmlspecialchars(substr($pass,0,7));
<input type="password" name="pass" title="Введите пароль" align="middle" class="login" maxlength="8">
|
Тупой md5 от пароля в 8 символов на текущем этапе мало кого останавливает.
Постраничная аутентификация опять сессионным идентификатором?
IP, конечно, проверяется - это плюс. Но в рамках одного внешнего IP ты сидишь голеньким. Налетай кто хочет...
Отдельно порадовал оборот "безопасность и другие недораборки". :)
PS. Чувствуется, что автор старался.
Не чувствуется, что вникнул в суть применяемых приемов и используемых функций.
А при этом ожидать результата от кода аутентификации как-то не приходится... | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 09:15)
| | 1.
$pass = mysql_escape_string($pass);
|
Trianon, А почему ошибка ?
2. Посоветуете какие методы защиты можно еще применить ? | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 09:24)
| | >1.
>
> $pass = mysql_escape_string($pass);
>
|
>
>Trianon, А почему ошибка ?
Нет, это Вы ответьте на вопрос "зачем оно зхдесь потребовалось?"
Когда ответите - поймете, в чем.
собственно $name = htmlspecialchars(substr($name,0,7)); после mysql_escape_string - тоже ошибка.
>2. Посоветуете какие методы защиты можно еще применить ?
Нельзя так ставить вопрос.
Даже в суп перед варкой нельзя просто так набросать ингридиенты. | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 09:28)
| | 1. Функция mysql_escape_string($pass) возвращает экранированную строку, вот и получаю строку перезаписывая полученное значение в переменную $name | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 09:33)
| | >1. Функция mysql_escape_string($pass) возвращает экранированную строку, вот и получаю строку перезаписывая полученное значение в переменную $name
Зачем Вам в этом месте экранированная строка?
Тот факт, что экранированная строка отличается от исходной, надеюсь, доказывать не надо? | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 09:52)
| | почитал, немного запутали в плане не эскейпирования пароля если брать во внимание вот эту http://softtime.ru/forum/read.php?id_forum=3&id_theme=68433 тему.
кстати,PhMaster, а зачем переменная $_SESSION['authorized'] ? разве $_SESSION['name'] не достаточно (ip само собой...) ? | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 10:10)
| | А почему запутал ? На мой вгляд решение хорошее, сначала выбирать пароль юзера по логину, а потом уже проверять пароль переденный в методом POST и выбранный из базы. | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 10:18)
| | это понятно . я не об этом. я про подводные камни которые обсуждались в теме по ссылке если не эскейпировать пароль | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 10:10)
| | Замечательно.
Значит Вам и карты в руки.
Значит Вы и ответите, почему в той теме нужно эскейпить, а в этой - нет . | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 10:22)
| | а я уж понадеялся что вы ответите :) | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 10:26)
| | А что не понятно ? Может я отвечу ? | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 10:36)
| | посмотрите в той теме по ссылке что бывает если не эскейпировать пароль и ответьте | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 09:33)
| | Trianon.
Тьфу!
Запрос сам переделывался потому и забыл, а вот так:
/вызов подключаемого модуля, отвечающего за вывод формы и авторизации
<?php
session_start();
if(!defined("MAIN")) return;
/*if ($_POST['session_id'] != session_id())
{
$error[] = "Попытка передачи данных с другого хоста. Скрипт остановлен.";
} */
if (isset($_POST['sub']))
{
$title_html = "Вход в систему";
///////////////////////////////////////////////////////////
// Блок подготовки и проверки
///////////////////////////////////////////////////////////
// Получаем данные отправленные методом POST
$name = trim($_POST['name']);
$pass = trim($_POST['pass']);
// Проверяем правильность ввода данных
if(empty($name) or empty($pass)) $error[] = "Ошибка: Вы не указали логин или пароль.";
if(empty($error))
{
// Подготавливаем переменные для добавления в SQL-запрос, экранируя
// все спецсимволы при помощи функции mysql_escape_string();
if (!get_magic_quotes_gpc())
{
$name = mysql_escape_string($name);
}
// заменяем все специальные символы эквивалентом
$name = htmlspecialchars(substr($name,0,7));
$query = "SELECT name,pass FROM users
WHERE name = '$name'";
list($m_name, $m_pass) = mysql_fetch_row(mysql_query($query));
if ($m_pass != md5($pass) or // даст TRUE, если пароли не равны
$name != $m_name)
$error[] = "Ошибка: Неверный логин или пароль.";
else
{
$_SESSION['authorized'] = true;
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['name'] = $name;
}
}
}
if (isset($_POST['out']))
{
// Уничтожить все переменные в сессии
$_SESSION = array();
// destroy the session
session_destroy();
// redirect to login page
echo "<HTML><HEAD>
<META HTTP-EQUIV='Refresh' CONTENT='0; URL=main.php'>
</HEAD></HTML>";
}
?>
<form method="post" title="Вход для пользователей">
<input name=session_id type="hidden" value=<?php echo session_id();?>>
<table cellspacing="0" border="0" cellpadding="0" class="login">
<tr>
<td colspan="4"><div id="text2">Имя пользователя:</b></div></div></td>
</tr>
<tr>
<td><img src="dataimg/input100.gif" width="6" height="20" border="0" alt=""></td>
<td><input type="text" name="name" title="Введите логин" class="login" align="middle" value='<?= $_SESSION['name'];?>' maxlength="8"></td>
<td><img src="dataimg/input200.gif" width="6" height="20" border="0" alt=""></td>
<td width="37"> </td>
</tr>
<tr>
<td colspan="4"><div id="text2">Пароль:</b></div></div></td>
</tr>
<tr>
<td><img src="dataimg/input100.gif" width="6" height="20" border="0" alt=""></td>
<td><input type="password" name="pass" title="Введите пароль" align="middle" class="login" maxlength="8"></td>
<td><img src="dataimg/input200.gif" width="6" height="20" border="0" alt=""></td>
<td valign="top"><!--<INPUT type="image" src="dataimg/but-ente.gif" align="middle" class="button">--></td>
</tr>
<tr>
<td></td>
<td align="center">
<?php
if (isset($_SESSION['name'])) echo "<input type=submit name=out value=Выйти class=button></td>";
else echo "<input type=submit name=sub value=Войти class=button></td>";
?>
<!--<input type="submit" name="sub" value="Войти" class="button"> </td>-->
<td></td>
<td width="37"> </td>
</tr>
</table>
</form>
|
| |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 09:56)
| | trianon все же по поводу супа, может пожскажите нужные ингридиенты для него. оторые в любом случаи будут нужны. Например, соль :))) | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 09:59)
| | Да, конечно.
Голова. | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 10:20)
| | Trianon а более конкретнее ? | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 10:20)
| | Trianon пишет:
Постраничная аутентификация опять сессионным идентификатором?
Вот здесь ввиду малого опыта, вопрос. А чем если не сессионым идентификатором ?
Есть ли варианты ? (до кукисов пока не добрался) | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 10:50)
| | Вы не могли, добравшись до сессий, не добраться до кукисов.
Просто потому, что механизм сессий базируется на кукисах. | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 10:50)
| | видимо должна быть защита от кражи сессии. т.е проверка на каждой странице например ip записанного в сессию при авторизации и текущего ip. | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 10:56)
| | >видимо должна быть защита от кражи сессии.
>т.е проверка на каждой странице например ip записанного в сессию при авторизации и текущего ip.
Вы исходный код автора поста прочли?
Он же эту проверку и выполняет. | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 09:56)
| | >Запрос сам переделывался потому и забыл, а вот так:
Я же написал "собственно $name = htmlspecialchars(substr($name,0,7)); после mysql_escape_string - тоже ошибка." | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 10:52)
| | то есть htmlspecialchars должно быть до mysql_escape_string я правильно понял ? Только вот почему так ? | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 10:58)
| | нет. Не так.
Ответ "почему", вы получите не раньше, чем ответите на вопрос "Когда и с какой целью требуется?" | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 10:59)
| | htmlspecialchars требуется чтобы недопустить выполнение к примеру какого-либо скрипта javascript вот я его и применяю. | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 11:04)
| | Нет. Не за этим. | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 11:04)
| | на выводе надо применять
не на при внесении же в базу данных опасаться выполнения какого-либо скрипта | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 10:58)
| | Trianon, так всё-таки скажите плиз по поводу экранирования пароля. не могу понять никак.... неужели от длины зависит? | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 10:59)
| | Причем тут длина! У вас набор символов будет разный.
Проверяйте логин регуляркой на допустимые символы и длину,
не пересылайте пароль в открытом виде, его легко перехватить и прочитать....и т.д. | |
|
|
|
|
|
|
|
для: GeorgeIV
(23.10.2009 в 11:04)
| | не могу въехать :)
Trianon:
Что при этом посчитает MD5()? Экранирующие слэши?
В чем сермяжный смысл ставить экранирование кавычек в шестнадцатеричной строке в зависимость от состояния магических кавычек?
тут вроде как понятно.
я:
хм... а зачем эскейпировать пароль если все-равно его перед занесением в базу через md5 прогонять???
Trianon:
чтобы можно было менять md5 на что-то свое. Да хотя бы md5($pwd, 1) . Два символа дописываешь - логика рушится.
поясните | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 11:08)
| | >поясните
в отрыве от контекста?! Гиблое дело. | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 10:59)
| | экранирование применяется для недопущения sql-инъекции. Запросы посмотрите, они разные в том скрипте и моем ! | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 11:07)
| | >экранирование применяется для недопущения sql-инъекции. Запросы посмотрите, они разные в том скрипте и моем !
Ответ неверный.
Экранирование применяется не за этим.
Недопущение инъекции - лишь побочный эффект экранирования. | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 11:08)
| | string mysql_escape_string ( string unescaped_string )
Функция экранирует все спец-символы в unescaped_string, вследствие чего, её можно безопасно использовать в mysql_query().
из мануала :) | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 11:15)
| | Ну что я могу сказать.
1. Это не мануал.
2. фтопку данный перевод.
3. Поглядите документ посвежее.
http://www.php.net/manual/en/function.mysql-real-escape-string.php
Заметьте, что прилагательное safe в его контексте адекватно переводится не как "безопасный", а как "верный" | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 10:59)
| | Я ничего не скажу по поводу экранирования пароля, потому что пароли экранироваться не должны.
( Неприменительно к текущему спору, по моему стойкому мнению, с паролями воодще ничего делать не следует, кроме вычисления хешей. )
вспоминайте (не помните - ищите ответ на вопрос) - когда и зачем требуется экранирование. | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 11:08)
| | ну а как же вот это при вычислении хешей?
$pass = "asdasd, 1";
md5($pass);
вы же писали что логика рушится. вот я и пытаюсь понять, почему там она рушится, а здесь нет | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 11:22)
| | По той же причине, по которой будет рушиться вкус пирожка с мясом , если из печи его сунуть в мясорубку.
Или если мясо для него сперва запинать в печь.
вроде и печь нужна и мяорубка - ан нет.
Технология нарушена.
Почему нарушена?
Потому что повар не понимает физики процессов, происходящих в мясорубке и в печи. | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 13:29)
| | еще б с шашлыком сравнили :)
однако сложный Вы человек :) | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 14:10)
| | Я так себе представляю, что Вы едите не только то, что сами себе готовите, но и то, что готовят другие люди (родственники, общепит, рестораны и т.п.)
И при этом, очевидно, желаете если не только вкусно поесть, но и не травануться, не нажить себе проблем с ЖКТ и пр.
Идея понятна?
Вот я, заходя и регистрируясь на том или ином портале, аутентификацию которого делаю не сам, тоже желаю, представьте себе.
Чтобы мой пароль не хранили, не оставляли в кукисах чужих машин, не пересылали открытым кодом, не заставляли ограничивать в диапазоне и пр.
так-то.
вероятность прокола и там и здесь примерно одинакова.
Этот портал тому подтверждение. | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 15:00)
| | идея предельно ясна.
>Вот я, заходя и регистрируясь на том или ином портале, аутентификацию которого делаю не сам, тоже желаю, представьте себе.
Чтобы мой пароль не хранили, не оставляли в кукисах чужих машин, не пересылали открытым кодом, не заставляли ограничивать в диапазоне и пр.
я тоже считаю что ограничивать пароль на какие-либо символы, держать в куках, в бд в открытом виде полный бред. я от вас совсем другого прошу! прошу чтобы вы объяснили почему в той теме нужно было хешировать чтобы md5 правильно сработала, а в этой - нет (я сам раньше никогда пароль не эскейпировал и не считал это нужным, но там Вы меня как-то переубедили, я имею ввиду про нарушение логики и тот пример в конце, а здесь как бы говорите обратное). Так что объясните пожалуйста всё-таки прямо, что за шляпа с этим md5 и что делать с паролем чтобы оан не волзникала если она вообще имеет место быть? (кстати ведь по сути вот это тоже не самый плохой вариант на крайняк:
ну допустим плохо применять mysql_escape_string к паролю при регистрации. но ведь что бы оно с ним не сделало, при последующей авторизации при применении той же mysql_escape_string проблем не возникнет. всё равно будет тот же результат например pa\'ssword как и при регистрации | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 15:14)
| | >прошу чтобы вы объяснили почему в той теме нужно было хешировать чтобы md5 правильно сработала, а в этой - нет
Где я в этой теме сказал, что пароль не нужно хешировать?
>(я сам раньше никогда пароль не эскейпировал и не считал это нужным, но там Вы меня как-то переубедили, я имею ввиду про нарушение логики и тот пример в конце, а здесь как бы говорите обратное).
Пля.
Нужно ескейпить не пароль!
Пароль ескейпить не нужно!
C паролем кроме хеширования вообще ничего делать не нужно!
Но!
Нужно ескейпить любую строку перед тем, как окружитть её кавычками! Из пароля она выползла , из числа, из хеша или из еще чего нибудь - пофиг!!! Ескейпить и всё! Просто! На всякий случай! Как помыть руки перед тем, как взяться за нож на кухне! Неважно, чистые они у тебя или нет!
PS. - Прошу извинить, был напуган. (с) | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 15:25)
| | спасибо. в общем-то теперь точно всё предельно ясно :)
>Где я в этой теме сказал, что пароль не нужно хешировать?
извиняюсь, я просто в понятиях запутался | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 11:08)
| | почитал мануал, в моем примере нужно htmlspechialchars обойтись. Такс или нет ? | |
|
|
|
|
|
|
|
для: PhMaster
(23.10.2009 в 11:25)
| | точно без.
когда будете выводить имя из базы в браузер, тогда и применяйте | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 11:30)
| | да, я допер уже. Спасибо!!! | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 11:30)
| | и еще как бы...
ну допустим плохо применять mysql_escape_string к паролю при регистрации. но ведь что бы оно с ним не сделало, при последующей авторизации при применении той же mysql_escape_string проблем не возникнет. всё равно будет тот же результат например pa\'ssword как и при регистрации | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 11:40)
| | http://php.inkz.ru/regist/index.php?a=1 | |
|
|
|
|
|
|
|
для: psychomc
(23.10.2009 в 11:40)
| | Вы что, храните пароль в открытом виде? На кой хрен с ним что то делать, если от него все равно будет получаться и храниться хэш!! Проверьте до этого на длину и допустимость символов и все. Не мудрите | |
|
|
|
|
|
|
|
для: GeorgeIV
(23.10.2009 в 11:47)
| | >Проверьте до этого на длину и допустимость символов и все. Не мудрите
Огрорчают сайты, где при регистрации написано: Пароль может состоять только из латинсих букв и цифр | |
|
|
|
|
|
|
|
для: Рома
(23.10.2009 в 11:52)
| | используйте буквы, цифры и некоторые "безопасные" символы (не допускайте, например, ввода <>).
Я думаю, что длина пароля гораздо важнее его состава. | |
|
|
|
|
|
|
|
для: GeorgeIV
(23.10.2009 в 12:06)
| | >не допускайте, например, ввода <>
Но почему?!
>Я думаю, что длина пароля гораздо важнее его состава.
Играют обе величины. | |
|
|
|
|
|
|
|
для: Trianon
(23.10.2009 в 13:33)
| | Тэгов уже точно не будет | |
|
|
|
|
|
|
|
для: GeorgeIV
(23.10.2009 в 14:16)
| | name: GeorgeIV
pass: <?php echo '<b>GeorgeIV</b>'; ?>
выходит такая связка опасна? | |
|
|
|
|
|
|
|
для: GeorgeIV
(23.10.2009 в 14:16)
| | Э... какие теги в пароле? Вы о чем? | |
|
|
|
|
|
|
|
для: GeorgeIV
(23.10.2009 в 11:47)
| | я сам это всё прекрасно понимаю! я написал что хеш будет тот же.
дело в другом.
гляньте просто вот эту тему.
http://softtime.ru/forum/read.php?id_forum=3&id_theme=68433
меня интересует проблема вычисления самого хеша при присутствии в исходном пароле некоторых символов о которой говорил Trianon. что делать с паролями я знаю | |
|
|
|