Ru-MaNGOS

Ru-MaNGOS (http://mangos.ytdb.ru/index.php)
-   WWW (http://mangos.ytdb.ru/forumdisplay.php?f=23)
-   -   Простая страница восстановления пароля (http://mangos.ytdb.ru/showthread.php?t=1345)

deadangel 01.06.2010 09:16

Простая страница восстановления пароля
 
Написал простой скрипт восстановления пароля. Пароль в БД меняется, но в игру все равно заходит по старому паролю. Вопрос, как можно сделать так, чтобы после смены пароля сразу в игру можно было зайти по новому паролю?

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


PHP код:

<?=header('Content-type: text/html; charset=utf-8');?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
<head>
    <title>Смена пароля для аккаунта World of Warcraft</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <meta name="author" content="Kazakou V. Andrey" />
    <meta name="email" content="a.v.kazakou@gmail.com" />
</head>
<body>

<?php
function error($str '')
{
    echo 
"<p class=\"error\">$str</p></body></html>";
    exit;
}

function 
sendPassword($login$email)
{
    
mysql_connect('<host>','<login>','<password>') or die(error('Ошибка! Невозможно соедениться с базой данных.'));
    
mysql_select_db('realmd');

    
$login mysql_real_escape_string($login);
    
$email mysql_real_escape_string($email);

    
$result mysql_query('SELECT COUNT(*) as validation FROM `account` WHERE `username` LIKE \''.$login.'\' AND `email` LIKE \''.$email.'\'') or die(error('Ошибка! Невозможно выполнить запрос в БД'));
    
$result mysql_fetch_array($result);
    if(
$result***91;'validation'***93;!=1error('Данная связка Логина и E-mail не обнаружена');

    
$psswd str_shuffle(substr(md5(rand(1,1024)), 06));
    
$sql "UPDATE `account` SET `sha_pass_hash`=SHA1(UPPER(CONCAT('$login',':','$psswd'))), `locked`=0, `v`=NULL, `s`=NULL, `sessionkey`=NULL  WHERE `username`='$login' AND `email`='$email'";
    
$result mysql_query($sql) or die(error(mysql_error().'</p><p>'.$sql));
    if(
mysql_affected_rows()!=1error('Невозможно изменить пароль в базе данных');

    
$to      $email;
    
$subject 'Смена пароля для World of Warcraft';
    
$message 'Ваш новый пароль для аккаунта '.$login.' в игре World of Warcraft: '.$psswd;
    
$headers 'From: robot@example.com' "\r\n" .
        
'Reply-To: robot@example.com' "\r\n" .
        
'Content-type: text/plain; charset=UTF-8' "\r\n" .
        
'X-Mailer: PHP/' phpversion();

    
$mailSended mail($to$subject$message$headers);
    if(!
$mailSendederror('Невозможно отправить письмо с новым паролем.');

    
error('Письмо с новым паролем выслано на указаный адрес.');
}
?>

<?php
    
if(!empty($_POST) and isset($_POST***91;'login'***93;) and isset($_POST***91;'email'***93;)) sendPassword($_POST***91;'login'***93;, $_POST***91;'email'***93;);
?>

    <form action="newpass.php" method="post">
    <table summary="">
            <tr>
                    <td>Имя аккаунта:</td>
                    <td><input type="text" name="login" value="" size="30"  /></td>

            </tr>
            <tr>
                    <td>Адрес e-mail:</td>
                    <td><input type="text" name="email" value="" size="30"  /></td>
            </tr>
            <tr>
                    <td colspan="2"><input type="submit" name="submit" value="Выслать новый пароль"  /></td>
            </tr>
    </table>
    </form>
</body>
</html>


Mic 01.06.2010 09:23

Кажется, нужно по пути обнулить поля "s" и "v". Ну и про экранирование переменных перед подстановкой в запросы тоже не стоит забывать.

Кот ДаWINчи 01.06.2010 10:48

Цитата:

Сообщение от Mic (Сообщение 7768)
Кажется, нужно по пути обнулить поля "s" и "v". Ну и про экранирование переменных перед подстановкой в запросы тоже не стоит забывать.

Правильно. И еще можно занулить sessionkey

Вот тут:

Цитата:

$sql = "UPDATE `account` SET `sha_pass_hash`=SHA1(CONCAT(UPPER('$login'),':',UP PER('$psswd'))), `locked`=0 WHERE `username` LIKE '$login' AND `email` LIKE '$email'";

alien 01.06.2010 18:36

Только использовать LIKE в данном запросе совершенно неверно.
Да и вобще если использовать текущий вариант скрипта не безопасно.

deadangel 02.06.2010 11:39

Потенциально LIKE конечно опасен, но в конкретном случае я не вижу проблемы, как с его помощью можно взломать БД. Более того, у меня база персонажей хранится уже 3 года и раньше пользователи создавали имена аккаунтов в разном регистре и по сей день вводят их в этом регистре. Если ставить вместо Like условие равенства, то большая часть запорется. Т.к. все аккаунты давно уже хранятся в UP регистре.

Спасибо всем. В запросе установил обнуление полей V, S и sessionkey. пароль начал меняться как положено. Вот работающая версия скрипта. Может кому нибудь и пригодится :)

Код:

    $psswd = str_shuffle(substr(md5(rand(1,1024)), 0, 6));
    $sql = "UPDATE `account` SET `sha_pass_hash`=SHA1(CONCAT(UPPER('$login'),':',UPPER('$psswd'))), `locked`=0, `v`=NULL, `s`=NULL, `sessionkey`=NULL  WHERE `username` LIKE '$login' AND `email` LIKE '$email'";
    $result = mysql_query($sql) or die(error(mysql_error().'</p><p>'.$sql));


alien 02.06.2010 11:58

Вместо использования достачно внести в настройки sql нечуствительность регистра при равенстве.
А помешать очень просто можно сбросить пароль другому человеку.

deadangel 02.06.2010 12:18

Согласен. Если добавить % в имя пользователя, то как вариант он сбросит пароли. В таком случае придется делать регистронезависимое сравнение и для e-mail. :) Сейчас переделаю и сброшу окончательный вариант.

deadangel 02.06.2010 14:16

Вот окончательный вариант скрипта перенес в первый пост. Кто нибудь может подсказать его потенциально опасные моменты? В принципе у меня сервер настроен на независимость регистров при сравнении. Но если кому-то понадобится, то проще данные пользователя и БД приводить к верхнему регистру. :) В общем всех благодарю за помощь.

tempura 02.06.2010 16:38

Оба молодцы! :)


Простите, но просто вот ради именно такого общения и создан форум. Не ради "дайти ресофку скочадь", а ради вас, ребята! :)

Mic 04.06.2010 11:21

PHP код:

if(!empty($_POST)) sendPassword($_POST***91;'login'***93;, $_POST***91;'email'***93;); 

- потенциальный источник notice'ов. Массив-то может и не пустой, но этих элементов там может не быть.
Ну и мелкая придирочка ;) CONCAT(UPPER('foo'), ':', UPPER('bar')) == UPPER(CONCAT('foo', ':', 'bar'))

deadangel 04.06.2010 14:49

Поправил скрипт в первом посте. Спасибо за информацию :)


Текущее время: 18:44. Часовой пояс GMT +3.

ru-mangos.ru - Русское сообщество MaNGOS