|
|
|
| Здравствуйте, уважаемые Знатоки! (сказано с уважением, поэтому банить не надо))))
У меня небольшие трудности. Дело в том, что на моём сайте авторизация идёт на кукиз (сессии, почему-то барахлят, и часто выбивает), и я немного обеспокоен безопасностью своих приложений.
Посему у меня вопрос:
Когда пользователь авторизовывается, среди прочих значений передаётся следущее:
setcookie('login', $log, time()+30*86400);
setcookie('pw', $password, time()+30*86400);
В качестве пароля тут - его md5 шифр, хранящийся в файле (когда пользователь регистрируется, в файл записывается не пароль, а его md5 зашифровка).
В начале каждой страницы я делаю вот что:
<?php
require_once('system.php');
top('Главная страница');
.....
.....
.....
down()
?>
Когда подключаю "require_once('system.php');", в этом файле выполняется среди всего прочего следущие строчки:
include "users/$_COOKIE[login].php";
if($_COOKIE[pw]!=$password) exit;
Скажите, это - нормальная защита приложения от чужого "вмешательства" с целью делать "плохие" вещи под чужим логином? Достаточно защищено, или посоветуете сделать что-то ещё?
И ещё один вопрос - на каждой странице у меня подключается примерно три-четыре внешних файла. Это сильно скажется на работе сервера (я пользуюсь бесплатным хостингом)? Средний онлайн на каждый час - 50 человек. Не вынесет мне администрация ресурса предупреждение из-за нагрузок (будем считать, что выполнение каждого скрипта малозначительное, и на нагрузку не влияет - спрашивается только про многочисленные включения других файлов в сценарий)? | |
|
|
|
|
|
|
|
для: as67ji
(10.07.2009 в 13:22)
| | > include "users/$_COOKIE[login].php";
Этим Вы позволяете пользователю исполнить любой файл сервера, какой он только захочет, как php-скрипт.
О какой безопасности может идти речь? | |
|
|
|
|
|
|
|
для: as67ji
(10.07.2009 в 13:22)
| | некоторые скрипты загружают целые библиотеки пользовательских функций по несколько сотен килобайт запутанного кода - и ничего, пусть это вас не волнует, главное - что бы код был оптимизирован.
//
Главная уязвимость вашего метода авторизации в скрипте - это, конечно же, include "users/$_COOKIE[login].php"; , который позволяет загрузить ЛЮБОЙ участок вашего кода, и это самая частая узвимость скриптов.
для начала вам нужно узнать, какие символы в имени юзера разрешены.
Например, только англ. и цифры.
Тогда надо сделать проверку:
if(!preg_match('/^[a-z0-9]+$/i', $_COOKIE['login'])) { exit('Попытка открыть чужой файл'); }
или что-то типу этого, то есть, главное в принципе - не разрешить символы .. (две точки подряд - поднятся папкой выше) и / (символ папки)
Другой совет, по слухам $_COOKIE[login] работает мало не в 10 раз медленнее чем $_COOKIE['login'] (в кавычках) - поэтому советую пользоваться только ими.
Да, и на конец ещё совет - лучше уже со стороны кода сделать так:
include 'users/'.$_COOKIE['login'].'.php';
и главное проверка куки.
Вот так.
Может я ошибаюсь, тогда более опытные участники меня исправят. | |
|
|
|
|
|
|
|
для: Akdmeh
(10.07.2009 в 13:31)
| | Akdmeh, огромное спасибо! Да, я как-то не подумал насчет "users/$_COOKIE[login].php"; , а стоило бы... Ещё раз спасибо, это действительно большая дырка *ушел исправлять*
Но вот ещё момент - когда кто-то регистрируется, его ник заносится в базу:
include 'allusers.php';
$u=sizeof($user)+1;
$fh=fopen("allusers.php", "a");
fwrite($fh, "<? \$user[$u]=\"$log\"; ?>");
fclose($fh);
Может, помимо "if(!preg_match('/^[a-z0-9]+$/i', $_COOKIE['login'])) { exit('Попытка открыть чужой файл'); }" стоит подключать этот файл (allusers.php) и в цикле проверить есть ли такой ник, и только тогда проверять это условие для большей надёжности (но тогда возникает вопрос - если зарегестрировано больше тысячи, цикл будет тормозить сценарий...)? | |
|
|
|
|
|
|
|
для: As67ji
(10.07.2009 в 13:49)
| | а не проще ли при подключении сделать проверку(псевдокод):
if(файл_существует(имя_пользователя)) { проверить пароль}
else { пользователя существует. соответственно пароль проверять не надо} | |
|
|
|
|
|
|
|
для: Akdmeh
(10.07.2009 в 14:13)
| | Akdmeh, хм, да, наверное. Я всё сделал как вы и советовали, спасибо ещё раз. | |
|
|
|
|
|
|
|
для: Akdmeh
(10.07.2009 в 14:13)
| | Вот так нормально будет?
if(!preg_match("#^[a-z0-9_@]{2,20}$#i", $_COOKIE['login']))
{
header("Location: http://google.ru"); exit;
}
if(file_exists("users/".$_COOKIE['login'].".php"))
{
include "users/".$_COOKIE['login'].".php";
}
elseif(file_exists("../users/".$_COOKIE['login'].".php"))
{
include "../users/".$_COOKIE['login'].".php";
}
else
{
header("Location: http://google.ru"); exit;
}
if($_COOKIE['pw']!=$password)
{
header("Location: http://google.ru"); exit;
}
|
| |
|
|
|
|
|
|
|
для: As67ji
(10.07.2009 в 15:04)
| | Идея ясна, но вот это сделано плохо:
file_exists("../users/" ...
file_exists("users/"
нужно думать, где вы находитесь относительно корня скрипта, это уже называется быдлокодерством(без обид).
А через месяц будете добавлять
file_exists("../../users/"
file_exists("../../../users/"
? | |
|
|
|
|
|
|
|
для: Akdmeh
(10.07.2009 в 15:16)
| | Предложите другой вариант?) | |
|
|
|
|
|
|
|
для: As67ji
(10.07.2009 в 15:29)
| | раньше я юзал константу WAY
например
define('WAY', '');
значит, что скрипт в корне. а файлы подключал через include WAY.'file.php';
А если я был в подпапке от корня, то в файле прописывал define('WAY', '../');
ну как это делать вам - подумайте сами, может придумаете свой способ | |
|
|
|
|
|
|
|
для: As67ji
(10.07.2009 в 15:29)
| | Тут нашел у себя один из превых своих скриптов написанных на php(вроде пока ничего страшного не случилось с сайтами которые его использауют), состоит из 2-х файлов, первый обрабатывает введенные данные в форму входа и присваетвает куки, второй включается в начало каждой страницы и закрывает дотсуп если не существуют нужные куки.
файл-обработчик данных полученных с формы входа:
<?
if (isset($HTTP_POST_VARS['GLOBALS']) || isset($HTTP_POST_FILES['GLOBALS']) || isset($HTTP_GET_VARS['GLOBALS']) || isset($HTTP_COOKIE_VARS['GLOBALS']))
{
die("Hacking attempt");
}
// Protect against HTTP_SESSION_VARS tricks
if (isset($HTTP_SESSION_VARS) && !is_array($HTTP_SESSION_VARS))
{
die("Hacking attempt");
}
$protected = "AQwjliIIsad15775QQvvbmk";
include("bloks/bd.php");
if (isset($_POST['user']))
{
$user = $_POST['user'];
}
if (isset($_POST['pass']))
{
$pass = $_POST['pass'];
}
$result = mysql_query("select * from auth where user='$user'",$db);
if (!$result)
{
echo "<p>Возникла ошибка с базой данных.";exit (mysql_error());
}
if(mysql_num_rows($result) > 0) //проверяет если пользователь в базе
{
$myrow = mysql_fetch_array($result);
$id = $myrow['id'];
}
else
{
echo "<p>В базе нет такого пользователя</p>";
exit();
}
if ($pass == $myrow['pass']) {
setcookie ("user", $user);
setcookie ("id", $id);
setcookie ("provvv", 4568872);
echo "<html>
<head><meta http-equiv='Refresh' content='0; URL=***'>
</head>
</html>";//переадресовка на нужную страницу
}
else {echo "<html>
<head>
<title>Неверный пароль</title>
</head>
<body> Был введен неверный пароль! Вернитесь <input name='back' type='button' value='назад' onclick='history.back(); '/> и введите правильный пароль.
</html>"; } ?>
|
Файл лок который подключается в начало каждого "засекреченного раздела":
<?
if(!isset($protected) OR $protected != "AQwjliIIsad15775QQvvbmk") {exit("Ошибка!");}
if (!isset($_COOKIE['provvv']) or $_COOKIE['provvv'] != '4568872') { echo "<html><head><title>Незарегистрированный пользователь</title>
</head><body><p>Вы не можете просмотреть данную страницу</p>
</body></html>
";
exit();}
if (isset($_COOKIE['user'])) // раз дошли до этого места значит куки были 100% присвоены проверяем на соответствие
{
$user = $_COOKIE['user'];} else {exit("Проблема с COOKIE (не опредилился автор).");}
if (isset($_COOKIE['id']))
{
$user_id = $_COOKIE['user_id'];}
else {exit("Проблема с COOKIE");}
echo "<font color='#CC6633'>Вы находитесь на сайте как: ".$user."</font>";
include("bloks/bd.php");
$result = mysql_query("select * from auth where user='$user' AND id = '$user_id'",$db);
if (!$result)
{
echo "<p>Возникла ошибка с базой данных. <strong>Сообщите администратору:tropnikovvv1@yandex.ru</strong></p>";
exit (mysql_error());
}
if(mysql_num_rows($result) != 1) // небольшая проверочка на косяки(вдруг 2 пользователя с одним ником каким-то образом попали в базу
{
echo "<p>Не могу определиться с пользователем. Скорей всего ошибка произошла не по вашей вине. Напишите пожалуйста об ошибке:***или в <a href='gb.php'>гостевую</a></p>";
exit();
}
?>
|
Более менее приличный скрипт, но на админскую часть его лучше не ставить так как куки в принципе можно утащить. И желательно конечно файл lock не подключать, а прописывать его код в начале каждой страницы.
Более надежную защиту можно составить на основе вот этого:
Header ("WWW-Authenticate: Basic realm=\"Admin Page\"");
Header ("HTTP/1.0 401 Unauthorized");
$_SERVER['PHP_AUTH_USER'] = mysql_escape_string($_SERVER['PHP_AUTH_USER']);
$_SERVER['PHP_AUTH_PW'] = mysql_escape_string($_SERVER['PHP_AUTH_PW']);
Но это уже другая история потому что для обычного пользователя это будет выглядеть немного непривлекательно, обычно это используют только для админок. | |
|
|
|
|
|
|
|
для: tvv123456
(10.07.2009 в 16:11)
| | tvv123456,
Header ("WWW-Authenticate: Basic realm=\"Admin Page\"");
Header ("HTTP/1.0 401 Unauthorized");
|
не пашет у меня - php не так установлен, чтобы использовать эту авторизацию.
Насчёт того кода что вы показали - некоторые идеи можно использовать, но в целом мне не подходит.
Akdmeh, использование констант штука полезная... Но прописывать их в огромное количество файлов что-то не сильно хочется... Проще оставить всё "as is". | |
|
|
|
|
|
|
|
для: as67ji
(10.07.2009 в 13:22)
| | Не хотел создавать новую тему...
Подскажите, что обозначает ошибка
Warning: Cannot use a scalar value as an array in C:\php\Apache2\htdocs\news.php on line 2
Warning: Cannot use a scalar value as an array in C:\php\Apache2\htdocs\news.php on line 3
Warning: Cannot use a scalar value as an array in C:\php\Apache2\htdocs\news.php on line 4
Warning: Cannot use a scalar value as an array in C:\php\Apache2\htdocs\news.php on line 5
Warning: Cannot use a scalar value as an array in C:\php\Apache2\htdocs\news.php on line 6
Warning: Cannot use a scalar value as an array in C:\php\Apache2\htdocs\news.php on line 7
Warning: Cannot use a scalar value as an array in C:\php\Apache2\htdocs\news.php on line 8
Warning: Cannot use a scalar value as an array in C:\php\Apache2\htdocs\news.php on line 9
Warning: Cannot use a scalar value as an array in C:\php\Apache2\htdocs\news.php on line 10
Warning: Cannot use a scalar value as an array in C:\php\Apache2\htdocs\news.php on line 11
Warning: Cannot use a scalar value as an array in C:\php\Apache2\htdocs\news.php on line 12
|
| |
|
|
|
|
|
|
|
для: as67ji
(11.07.2009 в 11:21)
| | Это не ошибка, а предупреждение, что ждали массив, а пришла просто переменная.
Это не страшно, можно проигнорировать, если логика работы не нарушается | |
|
|
|
|
|
|
|
для: GeorgeIV
(11.07.2009 в 11:29)
| | Ммм... Что может быть? | |
|
|
|
|
|
|
|
для: GeorgeIV
(11.07.2009 в 11:29)
| | Ммм... Что может быть?
Допустим, у меня массив $arr, а где-то позже я случайно сделал $arr=6...
И при выводе for(...) { print $arr[$i]; } вылетит эта ошибка? | |
|
|
|
|
|
|
|
для: as67ji
(11.07.2009 в 11:44)
| |
$arr = 6;
$i = 3;
print $arr[$i];
|
Какой реакции Вы ожидаете? | |
|
|
|
|
|
|
|
для: GeorgeIV
(11.07.2009 в 11:29)
| | >Это не ошибка, а предупреждение, что ждали массив, а пришла просто переменная.
>Это не страшно, можно проигнорировать, если логика работы не нарушается
Я бы сказал по-другому.
Если при таком предупреждении не нарушается логика, значит любая логика в скрипте отсутствует напрочь. А значит и вправду нестрашно. | |
|
|
|