Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Безопасность с cookies... А также скорость скриптов.
 
 автор: as67ji   (10.07.2009 в 13:22)   письмо автору
 
 

Здравствуйте, уважаемые Знатоки! (сказано с уважением, поэтому банить не надо))))

У меня небольшие трудности. Дело в том, что на моём сайте авторизация идёт на кукиз (сессии, почему-то барахлят, и часто выбивает), и я немного обеспокоен безопасностью своих приложений.

Посему у меня вопрос:

Когда пользователь авторизовывается, среди прочих значений передаётся следущее:

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 человек. Не вынесет мне администрация ресурса предупреждение из-за нагрузок (будем считать, что выполнение каждого скрипта малозначительное, и на нагрузку не влияет - спрашивается только про многочисленные включения других файлов в сценарий)?

  Ответить  
 
 автор: Trianon   (10.07.2009 в 13:28)   письмо автору
 
   для: as67ji   (10.07.2009 в 13:22)
 

> include "users/$_COOKIE[login].php";

Этим Вы позволяете пользователю исполнить любой файл сервера, какой он только захочет, как php-скрипт.
О какой безопасности может идти речь?

  Ответить  
 
 автор: Akdmeh   (10.07.2009 в 13:31)   письмо автору
 
   для: 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';

и главное проверка куки.
Вот так.

Может я ошибаюсь, тогда более опытные участники меня исправят.

  Ответить  
 
 автор: As67ji   (10.07.2009 в 13:49)   письмо автору
 
   для: 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) и в цикле проверить есть ли такой ник, и только тогда проверять это условие для большей надёжности (но тогда возникает вопрос - если зарегестрировано больше тысячи, цикл будет тормозить сценарий...)?

  Ответить  
 
 автор: Akdmeh   (10.07.2009 в 14:13)   письмо автору
 
   для: As67ji   (10.07.2009 в 13:49)
 

а не проще ли при подключении сделать проверку(псевдокод):
if(файл_существует(имя_пользователя)) { проверить пароль}
else { пользователя существует. соответственно пароль проверять не надо}

  Ответить  
 
 автор: As67ji   (10.07.2009 в 14:19)   письмо автору
 
   для: Akdmeh   (10.07.2009 в 14:13)
 

Akdmeh, хм, да, наверное. Я всё сделал как вы и советовали, спасибо ещё раз.

  Ответить  
 
 автор: As67ji   (10.07.2009 в 15:04)   письмо автору
 
   для: 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;
}

  Ответить  
 
 автор: Akdmeh   (10.07.2009 в 15:16)   письмо автору
 
   для: As67ji   (10.07.2009 в 15:04)
 

Идея ясна, но вот это сделано плохо:
file_exists("../users/" ...
file_exists("users/"
нужно думать, где вы находитесь относительно корня скрипта, это уже называется быдлокодерством(без обид).
А через месяц будете добавлять
file_exists("../../users/"
file_exists("../../../users/"
?

  Ответить  
 
 автор: As67ji   (10.07.2009 в 15:29)   письмо автору
 
   для: Akdmeh   (10.07.2009 в 15:16)
 

Предложите другой вариант?)

  Ответить  
 
 автор: Akdmeh   (10.07.2009 в 15:51)   письмо автору
 
   для: As67ji   (10.07.2009 в 15:29)
 

раньше я юзал константу WAY
например
define('WAY', '');
значит, что скрипт в корне. а файлы подключал через include WAY.'file.php';
А если я был в подпапке от корня, то в файле прописывал define('WAY', '../');

ну как это делать вам - подумайте сами, может придумаете свой способ

  Ответить  
 
 автор: tvv123456   (10.07.2009 в 16:11)   письмо автору
 
   для: 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']);
Но это уже другая история потому что для обычного пользователя это будет выглядеть немного непривлекательно, обычно это используют только для админок.

  Ответить  
 
 автор: As67ji   (10.07.2009 в 20:14)   письмо автору
 
   для: 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   (11.07.2009 в 11:21)   письмо автору
 
   для: 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

  Ответить  
 
 автор: GeorgeIV   (11.07.2009 в 11:29)   письмо автору
 
   для: as67ji   (11.07.2009 в 11:21)
 

Это не ошибка, а предупреждение, что ждали массив, а пришла просто переменная.
Это не страшно, можно проигнорировать, если логика работы не нарушается

  Ответить  
 
 автор: as67ji   (11.07.2009 в 11:42)   письмо автору
 
   для: GeorgeIV   (11.07.2009 в 11:29)
 

Ммм... Что может быть?

  Ответить  
 
 автор: as67ji   (11.07.2009 в 11:44)   письмо автору
 
   для: GeorgeIV   (11.07.2009 в 11:29)
 

Ммм... Что может быть?
Допустим, у меня массив $arr, а где-то позже я случайно сделал $arr=6...
И при выводе for(...) { print $arr[$i]; } вылетит эта ошибка?

  Ответить  
 
 автор: Trianon   (11.07.2009 в 19:30)   письмо автору
 
   для: as67ji   (11.07.2009 в 11:44)
 

$arr = 6;
$i = 3;
print $arr[$i];


Какой реакции Вы ожидаете?

  Ответить  
 
 автор: Trianon   (11.07.2009 в 19:29)   письмо автору
 
   для: GeorgeIV   (11.07.2009 в 11:29)
 

>Это не ошибка, а предупреждение, что ждали массив, а пришла просто переменная.
>Это не страшно, можно проигнорировать, если логика работы не нарушается

Я бы сказал по-другому.
Если при таком предупреждении не нарушается логика, значит любая логика в скрипте отсутствует напрочь. А значит и вправду нестрашно.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования