Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Авторизация


Автор: manson 16.9.2009, 11:24
в общем, на моей страничке есть форма для авторизации пользователей. Данные о пользователях хранятся в таблице MySQL (логин, пароль и т.д.). Короче все стандартно... 
Проблема в том, что задание стоит следующим образом: ни в программном коде, не в базе данных, пароль не должен храниться в открытом виде (для обеспечения безопасности).

Подскажите, плз, в каком направлении двигаться...


Автор: Ипатьев 16.9.2009, 11:30
пароль, которых хранится в базе, можно хэшировать функцией sha1()

Добавлено через 1 минуту и 44 секунды
И давайте разделять понятия.
Если речь идет о безопасности, то давайте говорить о безопасности.
Если речь идет о некоем "задании", то давайте забудем о безопасности, и будем говорить об этом задании.

Автор: MoLeX 16.9.2009, 11:37
manson, вариантов два:
1. использовать стандартные ф-ции шифрования\хеширования
2. написать свою 

Автор: manson 16.9.2009, 13:01
ммм... я так понял речь идет о пхп-функциях шифрования?  smile 

Автор: NewDima 16.9.2009, 13:08
храни в базе хэш пароля
Код

md5($password)

Автор: Ипатьев 16.9.2009, 13:10
не шифрования, а хэширования.
пример доступен в документации, по имени функции.

Автор: OutlawZ 16.9.2009, 13:18
Манул рулит, в нем есть примеры использование функции шифрования:
Взято из мануала MD5
Цитата
 
<?php
$str = 'apple';

if (md5($str) === '1f3870be274f6c49b3e31a0c6728957f') {
    echo "Would you like a green or red apple?";
    exit;
}
?>


SHA1
Цитата

<?php
$str = 'яблоко';
                     
if (sha1($str) === '6099a566a619528259db5aa8d7a5aa2d4122259a') {
    echo "Желаете зеленое или красное яблоко?";
    exit;
}
?> 



Ну а если так то :

Код

$passwd = "lalalalal";
$cr = md5($password);
echo $cr;

или с sha1 

$passwd = "lalalalal";
$cr = sha1($password);
echo $cr;


То есть перед тем как пароль в БД запихнуть переменная с паролем скажем она методом пост передается $_POST['passwd'] должна пройти через функцию шифрования, можно записать так sha1($_POST['passwd']); и отпровляем ее в БД, только лучше отправить переменную $cr так как в ней функция шифрует полученный пароль от формы.

Автор: NewDima 16.9.2009, 14:14
OutlawZ, не ьщифрование, а хэширование

Автор: gcc 16.9.2009, 14:34
хэш sha1,md5,etc еще можно "закриптографировать" md5crypt http://www.usenix.org/events/usenix99/provos/provos_html/node10.html

так как через "Радужные таблицы" можно перебрать хэш и взломать пароль http://ru.wikipedia.org/wiki/Радужная_таблица

я вот ковырял PostfixAdmin

Код



//
// generate_password
// Action: Generates a random password
// Call: generate_password ()
//
function generate_password ()
{
   $password = substr (md5 (mt_rand ()), 0, 8);
   return $password;
}



//
// pacrypt
// Action: Encrypts password based on config settings
// Call: pacrypt (string cleartextpassword)
//
function pacrypt ($pw, $pw_db="")
{
   global $CONF;
   $password = "";
   $salt = "";

   if ($CONF['encrypt'] == 'md5crypt')
   {
      $split_salt = preg_split ('/\$/', $pw_db);
      if (isset ($split_salt[2])) $salt = $split_salt[2];

      $password = md5crypt ($pw, $salt);
   }

   if ($CONF['encrypt'] == 'system')
   {
      if (ereg ("\$1\$", $pw_db))
      {
         $split_salt = preg_split ('/\$/', $pw_db);
         $salt = $split_salt[2];
      }
      else
      {
         $salt = substr ($pw_db, 0, 2);
      }
      $password = crypt ($pw, $salt);
   }

   if ($CONF['encrypt'] == 'cleartext')
   {
      $password = $pw;
   }

   return $password;
}



function md5crypt ($pw, $salt="", $magic="")
{
   global $MAGIC;

   if ($magic == "") $magic = $MAGIC;
   if ($salt == "") $salt = create_salt (); 
   $slist = explode ("$", $salt);
   if ($slist[0] == "1") $salt = $slist[1];

   $salt = substr ($salt, 0, 8);
   $ctx = $pw . $magic . $salt;
   $final = hex2bin (md5 ($pw . $salt . $pw));

   for ($i=strlen ($pw); $i>0; $i-=16)
   {
      if ($i > 16)
      {
         $ctx .= substr ($final,0,16);
      }
      else
      {
         $ctx .= substr ($final,0,$i);
      }
   }
   $i = strlen ($pw);
   
   while ($i > 0)
   {
      if ($i & 1) $ctx .= chr (0);
      else $ctx .= $pw[0];
      $i = $i >> 1;
   }
   $final = hex2bin (md5 ($ctx));

   for ($i=0;$i<1000;$i++)
   {
      $ctx1 = "";
      if ($i & 1)
      {
         $ctx1 .= $pw;
      }
      else
      {
         $ctx1 .= substr ($final,0,16);
      }
      if ($i % 3) $ctx1 .= $salt;
      if ($i % 7) $ctx1 .= $pw;
      if ($i & 1)
      {
         $ctx1 .= substr ($final,0,16);
      }
      else
      {
         $ctx1 .= $pw;
      }
      $final = hex2bin (md5 ($ctx1));
   }
   $passwd = "";
   $passwd .= to64 (((ord ($final[0]) << 16) | (ord ($final[6]) << 8) | (ord ($final[12]))), 4);
   $passwd .= to64 (((ord ($final[1]) << 16) | (ord ($final[7]) << 8) | (ord ($final[13]))), 4);
   $passwd .= to64 (((ord ($final[2]) << 16) | (ord ($final[8]) << 8) | (ord ($final[14]))), 4);
   $passwd .= to64 (((ord ($final[3]) << 16) | (ord ($final[9]) << 8) | (ord ($final[15]))), 4);
   $passwd .= to64 (((ord ($final[4]) << 16) | (ord ($final[10]) << 8) | (ord ($final[5]))), 4);
   $passwd .= to64 (ord ($final[11]), 2);
   return "$magic$salt\$$passwd";
}

function create_salt ()
{
   srand ((double) microtime ()*1000000);
   $salt = substr (md5 (rand (0,9999999)), 0, 8);
   return $salt;
}

function hex2bin ($str)
{
   $len = strlen ($str);
   $nstr = "";
   for ($i=0;$i<$len;$i+=2)
   {
      $num = sscanf (substr ($str,$i,2), "%x");
      $nstr.=chr ($num[0]);
   }
   return $nstr;
}

function to64 ($v, $n)
{
   global $ITOA64;
   $ret = "";
   while (($n - 1) >= 0)
   {
      $n--;
      $ret .= $ITOA64[$v & 0x3f];
      $v = $v >> 6;
   }
   return $ret;
}


Автор: manson 16.9.2009, 14:39
Большое спасибо, OutlawZ! 
Только когда я обратно буду из базы доставать, как мне расшифровать?

Автор: NewDima 16.9.2009, 14:42
Да тебе не нужно расшифровывать, хэшь не имеет дешифратора (кроме грубой силы, о_О и не только)!!!
Тебе всеголишь нужно будет сравнивать хэш пришедшего пароля с хэшем в базе

Автор: manson 16.9.2009, 15:11
to NewDima! 
Логично. Спс

Автор: OutlawZ 16.9.2009, 15:22
Что бы сравнить хеши можно сделать что то вроде такого, из базы берем хеш по имени который было введено т.е придется составлять запрос такого вида:


Код

$query = select password from user where = '$_POST[name]';

То есть он выдаст поле хеша принадлежащие введенному имени, потом сравниваем вводимые данные с данными из БД

$query = select password from user where = '$_POST[name]';
$result = mysql_query($query) or die (mysql_error());
$row = mysql_fetch_array(result);

if ( $row[password] === $_POST['passwd'] ) 
{
   Пароль правильный
   делаем какие то операции
}else{
  Пароль неправильный либо такого нет
  запрос ввести заного или что нить такое :)
}


Ну думаю как то так smile)))

Забыл сказать что переменную $_POST['passwd'] надо перед тем как помещать в запрос проверить на опастные символы , с помощью рег выражения что бы не было ошибки запрос или какие нить хулиганы не получили доступ к бд.

Автор: Ипатьев 16.9.2009, 15:38
OutlawZ, вы забыли кое-что в своем замечательном коде.
Мне кажется, вы очень торопитесь все время.

Автор: MoLeX 16.9.2009, 16:14
OutlawZ, зачем все эти лишние телодвижения?
Код

$query = "SELECT * FROM `User` WHERE `name` = '".$_POST[name]." AND `pass` = '".md5($_POST['pass'])."' LIMIT 1';
...........

Автор: Ипатьев 16.9.2009, 16:28
только 
Код

или = '$_POST[name]' AND
или = '".$_POST['name']."' AND

иначе ошибки будут.

ну, и перед этим не забыть
Код

$_POST['name']=mysql_real_escape_string($_POST['name']);

а то многие забывают.

Автор: MoLeX 16.9.2009, 16:57
Цитата(Ипатьев @  16.9.2009,  16:28 Найти цитируемый пост)
иначе ошибки будут.

в новой Опере подсветка не работает


Цитата(Ипатьев @  16.9.2009,  16:28 Найти цитируемый пост)
а то многие забывают.

это само собой

Автор: nerezus 16.9.2009, 22:47
Цитата

$query = "SELECT * FROM `User` WHERE `name` = '".$_POST[name]." AND `pass` = '".md5($_POST['pass'])."' LIMIT 1';
 Может не надо показывать новичкам такой пример ###кода? Они могут подумать, что это нормально.

Автор: MoLeX 17.9.2009, 05:15
nerezus,покажи свой пример не 
Цитата(nerezus @  16.9.2009,  22:47 Найти цитируемый пост)
###кода


Автор: NewDima 17.9.2009, 06:24
MoLeX, не, ну хотя бы следование элементарным правилам безопасности (mysql_real_escape_string)

Автор: Gold Dragon 17.9.2009, 09:00
я конечно предполагаю что в логине могут использоваться любые символы, но думаю что лучше сразу предложить пользователю отказаться от "всяких кавычек", букв и цифр для имени достаточно даже в латинском алфавите smile

Просто я не совсем сторонник использования mysql_real_escape_string и уж тем более "WHERE `name` = '".$_POST[name]." ". Любые "пришлые" переменные нужно пропускать через фильтр, а не вставлять их прямо в запрос

зы
и всё же $_POST['name'] а не $_POST[name]

Автор: Ипатьев 17.9.2009, 09:19
Цитата(Gold Dragon @  17.9.2009,  09:00 Найти цитируемый пост)
Просто я не совсем сторонник использования mysql_real_escape_string и уж тем более "WHERE `name` = '".$_POST[name]." ". Любые "пришлые" переменные нужно пропускать через фильтр, а не вставлять их прямо в запрос

это никак не связанные между собой вещи.
фильтр - опционально. зависит от того, "пришлые данные" или "ушлые".
mysql_real_escape_string или подстановки - обязательно. без исключений.

я думаю, что nerezus, как раз имел в виду подстановки. 
поскольку при их использовании просто не возникает странных идей типа "я не сторонник корректного составления SQL запросов". мнения программиста никто не спрашивает, система молча занимается всем этим сама. В этом смысле подстановки гораздо безопаснее для начинающих программистов.



Автор: MoLeX 17.9.2009, 09:28
Цитата(Gold Dragon @  17.9.2009,  09:00 Найти цитируемый пост)
зы
и всё же $_POST['name'] а не $_POST[name] 

Цитата(MoLeX @  16.9.2009,  16:57 Найти цитируемый пост)
в новой Опере подсветка не работает

вижу свой код без всякого оформления, и не обращаю внимание на упячатки (умный и сам все поймет и исправить, нужна тока идея)



Цитата(NewDima @  17.9.2009,  06:24 Найти цитируемый пост)
MoLeX, не, ну хотя бы следование элементарным правилам безопасности (mysql_real_escape_string) 

Цитата(Ипатьев @  16.9.2009,  16:28 Найти цитируемый пост)
ну, и перед этим не забыть
Код

$_POST['name']=mysql_real_escape_string($_POST['name']);

а то многие забывают.

Цитата(MoLeX @  16.9.2009,  16:57 Найти цитируемый пост)
это само собой 


Автор: Gold Dragon 17.9.2009, 09:33
вот именно, начинающий программист должен заботится о безопасности "приходящих" данных, а не полагаться только на простое экранирование. Всё что приходит из $_REQUEST как минимум должно иметь вид
Код

$name = (isset($_POST['name'])) ? fFiltr($_POST['name']) : '';
// ----------------------
function fFiltr($str=''){
  // здесь приводим всё в порядок, например так
  $result = preg_replace('#[^a-zа-яё0-9,:(); +.-]#ui','', strip_tags(trim($str)));
  return $result;
}

что касается самого вопроса, то однозначно в базе хранится не пароль а хотя бы md5(пароль).. в принципе этого достаточно. А как только пришли данные $_POST['password'], то их сразу переделываем в $password = md5($_POST['password']). Меня иногда поражают сайты где при восстановлении пароля они мне присылают мой пароль в открытом виде smile

Автор: Ипатьев 17.9.2009, 09:39
Цитата(Gold Dragon @  17.9.2009,  09:33 Найти цитируемый пост)
Всё что приходит из $_REQUEST как минимум должно иметь вид

мне всегда странно 
читать такие советы
на форуме
ведь если бы форум им следовал
то такой совет 
невозможно было бы написать

Автор: MoLeX 17.9.2009, 09:45
Ипатьев, форум и средне статистический сайт - это не одно и тоже. Так что сравнивать их не следует

Автор: Gold Dragon 17.9.2009, 09:50
тогда напишу, чтобы Ипатьев понял
$_REQUEST - это ассоциативный массив, состоящий из содержимого $_GET, $_POST, $_COOKIE и $_FILES, т.е. то что приходит (может приходить) от пользователя... Указав $_REQUEST я тем самым расширил $_POST, или чтобы совсем понятно было, то указал не "яблоко", а "фрукты"

Автор: bars80080 17.9.2009, 09:54
таки соглашусь с Ипатьев, подвергать стандартному форматированию все входящие данные - это сродни трижды перекрестится и плюнуть через плечо, чтобы защита крепче стала

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

Автор: Gold Dragon 17.9.2009, 10:24
согласен, что входящие данные не обязательно так усердно проверять, но привыкать к этому нужно и необходимо.. Всё конечно зависть от целей и задач самого проекта. Хотя с другой стороны, я давно написал класс, который имеет набор часто используемых фильтров, например, таких как, мыло, сайт, телефон, имя, только цифры, только буквы. Он маленький и подцепив его в любой проект, я забываю про всякое экранирование smile

Автор: Ипатьев 17.9.2009, 11:02
Рекомендую автору топика не повторять ошибку Gold Dragon, который, даже после всех объяснений все равно не понял, что фитьтрация данных и составление SQL запросов - совершенно разные, никак не связанные между собой вещи.
И привязывать одно к другому - это в конечном итоге нанести вред безопасности сайта.
Тем более, что фраза про "забываю про всякое экранирование" - не более чем фантазия, и в реальности забыть не получится. Что я проиллюстрировал примером выше.

Автор: Gold Dragon 17.9.2009, 11:33
уважаемый Ипатьев, объясните что Вы хотите вообще сказать? Читая Ваши очень познавательные комментарии я понимаю что с Вами можно общаться только на языке энциклопедического словаря.

вот например это что такое вообще???
Цитата(Ипатьев @  17.9.2009,  12:02 Найти цитируемый пост)
что фитьтрация данных и составление SQL запросов - совершенно разные, никак не связанные между собой вещи
Конечно это абсолютно разные вещи, например, такие как бензин и машина, кирпич и раствор... 

Скрипт получает данные, они должны быть приведены в соответствие и составлен запрос. Каким это образом будет сделано решать разработчику. Я показал что существует ещё вариант кроме как экранирование. Если Вас не устраивает слово "фильтрация", то тогда замените его на "приведение данных в соответствие...". И экранирование к этому тоже относится(!). А вот то что Вы вставляете в SQL-запрос глобальную переменную - это не самый лучший вариант с точки зрения безопасности. Если вы пишите свои проекты исключительно для собственных нужд, то конечно это всё необязательно делать.. Но если проект в Интернете, да ещё и активно "общается" с пользователями, то безопасность должна занимать чуть-ли не половину проекта

Автор: Ипатьев 17.9.2009, 11:48
дело в том, что данные в запрос не обязательно попадают из пользовательского ввода.
а данные, введенные пользователем, не обязательно попадают в SQL запрос.


Автор: IZ@TOP 17.9.2009, 11:50

M
IZ@TOP
Не кормите Троллей!

Автор: Ипатьев 17.9.2009, 11:59
слушаюсь!

Хотя я не думаю, что это тролль. 
Скорее - добросовестное заблуждение.

Автор: shurup_312 17.9.2009, 15:03
Цитата
OutlawZ, зачем все эти лишние телодвижения?

А где тут лишние телодвижения? по мне так вполне нормальный запрос на авторизацию..

Автор: IZ@TOP 17.9.2009, 15:06
Ипатьев, не дождешься  smile 

Автор: MoLeX 17.9.2009, 15:09
Цитата(shurup_312 @  17.9.2009,  15:03 Найти цитируемый пост)
А где тут лишние телодвижения? по мне так вполне нормальный запрос на авторизацию.. 

зачем использовать два запроса, вместо одного?!

Добавлено через 21 секунду
Цитата(shurup_312 @  17.9.2009,  15:03 Найти цитируемый пост)
--------------------
Написание сайтов на PHP+MySQL/JS+jQuery/Ajax/HTML+CSS. 
ICQ:

Оо

Автор: Ипатьев 17.9.2009, 15:26
Да не, там, вроде, в обоих случаях запрос был один.
Просто в первом хэш сравнивается в скрипте, а во втором подставляется прямо в запрос.
Разница только в обработке, но не принципиальная. Хотя привычнее все в запросе писать.

Автор: Sentox 17.9.2009, 16:16
Gold Dragon, 
Я так же использую класс с фильтрами очень удобно 
+

Ипатьев, 
Цитата

Тем более, что фраза про "забываю про всякое экранирование" - не более чем фантазия, и в реальности забыть не получится. Что я проиллюстрировал примером выше.

Как Вы используете библиотеку PEAR DB то же экранируете  или в фреймворке тоже экранируете .
Об этом и говорил Gold Dragon,  установил класс (фильтр) для данных, конкретной области , в том числе и экранирование данных, и забыл.


Автор: IZ@TOP 17.9.2009, 17:06
Sentox, Вы немного путаете понятия. Фильтры на данные пользовательского ввода в программе - это логика (бизнес-логика, если хотите), а экранирование данных передаваемых в SQL-запрос обязательная процедура, которая ну никак не связана с тем, фильтровали вы данные прежде или нет.

Автор: Ипатьев 17.9.2009, 17:15
well
когда я вижу фразу
Цитата(Gold Dragon @  17.9.2009,  09:00 Найти цитируемый пост)

предложить пользователю отказаться от "всяких кавычек"
Просто я не совсем сторонник использования mysql_real_escape_string  
Любые "пришлые" переменные нужно пропускать через фильтр, а не вставлять их прямо в запрос

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



Автор: Sentox 17.9.2009, 17:26
Цитата(IZ@TOP @ 17.9.2009,  17:06)
Sentox, Вы немного путаете понятия. Фильтры на данные пользовательского ввода в программе - это логика (бизнес-логика, если хотите), а экранирование данных передаваемых в SQL-запрос обязательная процедура, которая ну никак не связана с тем, фильтровали вы данные прежде или нет.

Gold Dragon и я не это аргументировали.
То что 
Цитата
SQL-запрос обязательная процедура
 это понятно и так, и в аргументацию я привёл  
Цитата
конкретной области 
, что само собой обрабатывается своей предметной областью.

Если Вы вчитаетесь в 
Цитата

Тем более, что фраза про "забываю про всякое экранирование" - не более чем фантазия, и в реальности забыть не получится. Что я проиллюстрировал примером выше.

увидите разницу, что человек , не берусь утверждать, реально не понимает абстракции и наверное ООП  .

Автор: IZ@TOP 17.9.2009, 17:30
Цитата(Sentox @  17.9.2009,  18:26 Найти цитируемый пост)
Если Вы вчитаетесь в 
Цитата

Тем более, что фраза про "забываю про всякое экранирование" - не более чем фантазия, и в реальности забыть не получится. Что я проиллюстрировал примером выше.

увидите разницу, что человек , не берусь утверждать, реально не понимает абстракции и наверное ООП  .

Вы глубоко заблуждаетесь  smile 

Автор: Ипатьев 17.9.2009, 17:34
Давайте не будем говорить за Gold Dragon.
Приведите пример того, о чем говорите вы лично.
Возможно, мы говорим об одном и том же, но хочется разобраться.
О какой предметной области и о каких фильтрах идет речь?

Лично я подготовку данных для SQL запроса не называю словом "фильтрация". Поскольку такие действия фильтрацией, собственно, не являются. Возможно, разночтения только в этом.

Но, тем не менее, если вы наборсаете небольшй алгоритм, вида "вот фильтрация, делает то-то, вот квотинг, вот запрос, а предметная область 0 это такие-то данные ", то я буду вам очень благодарен.

Автор: Gold Dragon 17.9.2009, 21:00
Цитата(Ипатьев @  17.9.2009,  18:34 Найти цитируемый пост)
Лично я подготовку данных для SQL запроса не называю словом "фильтрация". 
Вот о чём и спор.. Ипатьев, понимаете, Вы пытаетесь навязать своё понимание терминологии всем., но чем хорош русский язык что в нём может родиться существительное, прилагательное или глагол лишь только по тому что человек ЭМОЦИОНАЛЬНО так решил.. вот например, "Чайник уже звенит от свиста" или более понятно "голова болит от понимания прочитанного".. Я же писал что если Вам не нравится слово "фильтрация", то замените его "приведение данных в соответствие". Вы привыкли вставлять глобальные переменные с экранированием сразу в запрос, а я приучил себя все глобальные отдавать локальным, локальные приводить в соответствие, запрос присваивать переменной, а уж потом переменную отдавать в запрос. 

Вот скажите мне зачем мне это нужно
Код

mysql_real_escape_string($_POST['name']);

если у меня, например, есть такое
Код

(int)$_POST['name']

кстати, вот это вообще считаю безобразием, использовать глобальную переменную
Код

$_POST['name']=mysql_real_escape_string($_POST['name']);



Автор: bars80080 17.9.2009, 21:01
Цитата(Gold Dragon @  17.9.2009,  21:00 Найти цитируемый пост)
кстати, вот это вообще считаю безобразием, использовать глобальную переменную

почему? ведь изначально для порядка рекомендуется не создавать лишних переменных, легче с ними потом обращаться

Автор: Ипатьев 17.9.2009, 21:07
Цитата(Gold Dragon @  17.9.2009,  21:00 Найти цитируемый пост)
если у меня, например, есть такое

если есть, то не нужно.
А если речь идет не о целочисленном значении, а строковом, вы как поступаете?

Добавлено через 30 секунд
bars80080, согласитесь, это совершенно не принципиальный вопрос.

Автор: Gold Dragon 17.9.2009, 21:16
Цитата(bars80080 @  17.9.2009,  22:01 Найти цитируемый пост)
ведь изначально для порядка рекомендуется не создавать лишних переменных, легче с ними потом обращаться 
ну  как-то имея глобальную переменную типа $_POST лучше её оставлять в первозданном виде.. А создавая локальную переменную в функции или классе.. так она после обработке исчезнит

Цитата(Ипатьев @  17.9.2009,  22:07 Найти цитируемый пост)
А если речь идет не о целочисленном значении, а строковом, вы как поступаете?
так я уже писал есть класс, в котором есть следующие функции
- телефон
- mail
- сайт
- только цифры
- только буквы
- буквы, цифры, знаки типа точки

а вот если предусмотрены кавычки, то я их заменяю альтернативой

Добавлено через 35 секунд
просто после обработки у меня по определению в запросе не будет "неожиданностей" smile

Автор: Ипатьев 17.9.2009, 21:25
Ну, на первый взгляд, такой подход не грозит немедленной опасностью. 
Он не совсем совместим с идеологией баз данных, но в небольших проектах, ориентированных только на веб, без развитого функционала - вполне можно применять.

Но другим его советовать я бы воздержался. 

Автор: bars80080 17.9.2009, 21:31
Цитата(Ипатьев @  17.9.2009,  21:07 Найти цитируемый пост)
огласитесь, это совершенно не принципиальный вопрос. 

есть такое

Цитата(Gold Dragon @  17.9.2009,  21:16 Найти цитируемый пост)
как-то имея глобальную переменную типа $_POST лучше её оставлять в первозданном виде

и такое есть

Цитата(Gold Dragon @  17.9.2009,  21:16 Найти цитируемый пост)
А создавая локальную переменную в функции или классе.. так она после обработке исчезнит. так я уже писал есть класс, в котором есть следующие функции

ну, это самый оптимальный, ИМХО, метод

Цитата(Gold Dragon @  17.9.2009,  21:16 Найти цитируемый пост)
просто после обработки у меня по определению в запросе не будет "неожиданностей"

у меня в обработке есть формат all, в нём с данными ничего не делается. данные только переприсваиваются массиву заявленных входящих переменных, а если таковой нет, то устанавливается значение по умолчанию. так что, неожиданности возможны
с другой стороны, когда я составляю запрос к БД, то делаю это примерно так:

Код

        $fields = array(
            array('date', TIME, 0),
            array('creator', $_SESSION['USER_ID'], 0),
            array('summa', $HTML->in['sum'], 0),
            array('name', $HTML->in['name'], 1),
            array('surname', $HTML->in['surname'], 1),
            array('email', $HTML->in['email'], 1),
        );
        $r = $DB->writeRow('insert', $DB->T['T_DOCS'], $fields, '', LOG);
где класс БД сам всё обработает, и тут уж точно у меня и голова не болит, и все обработки будут применены именно там, где им следует быть

Автор: Gold Dragon 17.9.2009, 21:35
странное суждение... мне кажется что наоборот в больших проектах "экранирование", фильтрацию", "приведение в соответствие" вообще нужно именно выделять в отдельный класс и расширять функционал... В настоящее время я даже сделал класс который просто обрабатывает все "приходящие переменные", т.е. получает к примеру $_POST, а возвращает массив ключ->значение

Автор: Ипатьев 17.9.2009, 21:55
ну вот опять мы снова вернулись к тому, с чего начали. 
никто не говорит, что фильтрация не нужна, или что для ее применения нельзя сделать класс.

речь о том, что есть стандартный механизм работы с БД.
и если его подменять такими вот костылями, то со временем будешь о них спотыкаться.

Автор: Sentox 17.9.2009, 23:32
Цитата(Ипатьев @ 17.9.2009,  21:55)
ну вот опять мы снова вернулись к тому, с чего начали. 
никто не говорит, что фильтрация не нужна, или что для ее применения нельзя сделать класс.

речь о том, что есть стандартный механизм работы с БД.
и если его подменять такими вот костылями, то со временем будешь о них спотыкаться.

 smile  Ох и консерватор
Предлагаю написать разрабам PHP убрать в нём ООП - такой себе огромный костыль, который в принципе никому не нужен так как есть стандартные механизмы работы с данными.
Впринципе это уже холивар на тему стоит ли применять абстракцию и ни к чему не приведёт.

bars80080

Код

 $fields = array(
            array('date', TIME, 0),
            array('creator', $_SESSION['USER_ID'], 0),
            array('summa', $HTML->in['sum'], 0),
            array('name', $HTML->in['name'], 1),
            array('surname', $HTML->in['surname'], 1),
            array('email', $HTML->in['email'], 1),
        );
        $r = $DB->writeRow('insert', $DB->T['T_DOCS'], $fields, '', LOG);

Цитата

где класс БД сам всё обработает, и тут уж точно у меня и голова не болит, и все обработки будут применены именно там, где им следует быть


Что и требовалось доказать  smile 

Автор: solenko 18.9.2009, 00:20
Цитата(Gold Dragon @  17.9.2009,  20:35 Найти цитируемый пост)
странное суждение... мне кажется что наоборот в больших проектах "экранирование", фильтрацию", "приведение в соответствие" вообще нужно именно выделять в отдельный класс и расширять функционал... В настоящее время я даже сделал класс который просто обрабатывает все "приходящие переменные", т.е. получает к примеру $_POST, а возвращает массив ключ->значение 

А это не зависит от размеров проекта. Просто нужно разделять три операции:
1. Валидация данных. Валидация - проверка дынных на смысловое содержания. Уже из определения оно не может быть централизовано, т.к. система в целом не должна даже представлять какого вида данные ожидает отдельная ее часть. При этом данные никоим образом не должны измениться -- если какие-то данные не подходят по смысловой нагрузке, то они должны быть отправлены на повторный ввод пользователю.
2. Подготовка данных к сохранению. Включает только преобразование данных в безопасный для сохранения вид. При этом данные никоим образом не должны измениться.
3. Подготовка данных к отображению. Опять же, данные ни коим образом не должны измениться. В большинстве случаев, пользователь должен лицезреть именно то, что он ввел в систему. Если это было нечто вроде 
Цитата

<sciript>alert(\'test\');</script>'; DROP TABLE users; 

то в таком виде он и должен их просмотреть. Наглядный пример в этом же сообщении строкой выше )
Исключение составляют только задачи, в которых нужно интерпретировать некоторые теги. Например, пользователю разрешено использовать html теги a, strong, em. И вот только теперь, в этом частном случае,  можно говорить о фильтрации. Тут нам нужно отобразить интерпретировать нектороые теги как теги, а некоторые, как текст, т.е. применить фильтр

Цитата(Sentox @  17.9.2009,  22:32 Найти цитируемый пост)
Ох и консерватор
Предлагаю написать разрабам PHP убрать в нём ООП - такой себе огромный костыль, который в принципе никому не нужен так как есть стандартные механизмы работы с данными.

Учитесь не только читать, но и понимать ) В данном случае под стандартным механизмом понимается отсутствие мифической суперфилтрации и присутствие надежного, проверенного и необходимого экранирования данных.

Автор: Simpliest 18.9.2009, 02:07
Я вот одного не пойму, почему бы не отказаться от экранирования и не работать с prepared statement?

Добавлено через 6 минут и 4 секунды
Цитата(Gold Dragon @  17.9.2009,  21:00 Найти цитируемый пост)

Цитата(Ипатьев @  17.9.2009,  17:34 Найти цитируемый пост)
Лично я подготовку данных для SQL запроса не называю словом "фильтрация". 

Вот о чём и спор.. Ипатьев, понимаете,


Понимаете ли, подготовка данных для SQL это действительно не фильтрация. Причем даже в буквальном прочтении слова "фильтровать" оно не подходит.

Автор: solenko 18.9.2009, 08:06
Цитата(Simpliest @  18.9.2009,  01:07 Найти цитируемый пост)
Я вот одного не пойму, почему бы не отказаться от экранирования и не работать с prepared statement?

1. От необходимости экранирования избавляют не prepared statement, а использование placeholders
2. Когда вы вызываете, например, PDO::prepare() это не имеет никакого отношения к prepared statement
3. А какая разница? Таким образом вы просто перекладываете эту работу на одну из стандартных библиотек, но экранирование все равно происходит ). Тут же речь не о том, как именно это делать, а о том что это делать нужно в принципе и где своевремменно это делать

Автор: Ипатьев 18.9.2009, 09:32
Цитата(Simpliest @  18.9.2009,  02:07 Найти цитируемый пост)
Я вот одного не пойму, почему бы не отказаться от экранирования и не работать с prepared statement?

Лично я - только "за". В смысле посоветовать другим. Лично мне способ не нравится за "ненаглядность".
Но в этом удивительном топике речь идет совсем о другом. 

solenko, я думаю, вы говорите об одном и том же, просто разными словами.
Плюс, насколько я понимаю, в нативных библиотеках никакого экранирования в полном смысле того слова не происходит. Данные просто отправляются отдельными пакетами, раздельно с запросом. Но это не принципиально. Это один из способов безопасной работы с SQL.

Этих способов, включая изобретения из этого топика я насчитал уже 4:
    1. строки прослешиваются и заключаются в кавычки, числа приводятся к нужному типу.
    2. prepared statements, они же подготовленные выражения, они же placeholders, они же употребленное мной выше слово "подстановки": запрос отдельно - данные отдельно.
    3. редко используемая hex-string
    4. способ Gold Dragon: физическое удаление спецсимволов из строки.

Самым безопасным следует признать способ номер 2. Хотя не без оговорок. Ибо ничто не помешает программисту собирать запрос с плейсхолдерами точно так же динамически. 
Самым неудачным - то, что придумал Gold Dragon. База данных задумана так, чтобы хранить все символы. Любые. А сознательно ограничивая функциональность БД, мы заранее раскладываем себе грабли, на которые впоследствии обязательно наступим. 

Автор: Simpliest 18.9.2009, 12:23
Цитата(solenko @  18.9.2009,  08:06 Найти цитируемый пост)
 Когда вы вызываете, например, PDO::prepare() это не имеет никакого отношения к prepared statement

С PDO как раз не работал. Но Ипатьев прав, я говорил о http://ua2.php.net/manual/en/function.pg-prepare.php
http://ua2.php.net/manual/en/function.ibase-prepare.php

Автор: Gold Dragon 18.9.2009, 12:33
Ипатьев, ну ты прям меня на пьедестал определил smile философ...

А может вернёмся к "Авторизации"... Я вообще-то и не утверждаю что база не должна хранить всё что хочется... Вот только ЗАЧЕМ? smile Я утверждаю что ВСЕ данные должны приводится в соответствие с задачей... Лично моё мнение, что в имени пользователя (логине) не должно быть кавычек и других спецсимволов, поэтому мне не нужно это экранировать, и я их просто убираю, ну или предлагаю пользователю самому их убрать. Пароль - думаю букв и цифр больше чем достаточно для составления пароля. Да и я не трогаю первоначальные данные вообще и оставляю их такими какими они пришли, для этого и существуют локальные переменные.

Ну уэ если на то пошло, то куда приятнее читать код когда используются функции класса (главное красиво и понятно назвать)


Да и что вы прицепились к слову ФИЛЬТРАЦИЯ? smile я уже давно поправился и сказал что имел в виду и даже пару раз уже озвучил конкретно smile


Кстати, и в проектах использую класс для работы с базой. Раньше тоже думал что зачем это нужно.. но все меняется, появляются новые требования и возможности.. По этому легче залезть в класс и подправить чем лопатить весь код.. Да и необходимые логи так проще вести, всё в одном месте


Автор: Ипатьев 18.9.2009, 12:53
Gold Dragon, http://forum.vingrad.ru/index.php?showtopic=273012&view=findpost&p=1969750 solenko очень подробно все расписал.
У него обработке данных посвящено три пункта. А ваше 
Цитата(Gold Dragon @  18.9.2009,  12:33 Найти цитируемый пост)
ВСЕ данные должны приводится в соответствие с задачей...

- это только первый из них.
И с ним никто не спорит.
Просто есть еще два.

Автор: nerezus 18.9.2009, 12:58
Цитата

nerezus,покажи свой пример не 
 Да зачем?
Но в нем нне будет следующих косяков:
1) Порчи входящих данных. Ты обрабатываешь входящие данные а потом работаешь с ними. При этом по ним непонятно, обработаны они или нет, поэтому из-за человеческого фактора ты можешь допустить SQL-inj.
При правильной работе с данными SQL-inj исключен и человеческий фактор не может на него повлиять.
2) Входящие данные могут быть использованы в нескольких местах(статистика и т.д.), при этом ты рискуешь, что они уже будут испорчены на предыдущем этапе.

Цитата

почему? ведь изначально для порядка рекомендуется не создавать лишних переменных, легче с ними потом обращаться
 Есть правило не портить входящие данные никогда. Не раз сталкивался с ним в литературе.

Цитата

Лично я подготовку данных для SQL запроса не называю словом "фильтрация". 
 Я тоже. И я с тобой согласен. Причем это мнение разделяют уважаемые члены phpclub.
Но у парней из Зенда другое мнение - попробуй сдать тест на ZCE. Я завалил разделы Security и PHP4(все остальное на Excellent). Security завалена по этой причине. Когда же стал читать их ман, то увидел, что у нас просто разница в терминологии, и обработку по непонятным причинам они называют фильтрацией.

Автор: IZ@TOP 18.9.2009, 15:44

M
IZ@TOP
Модератор: Давайте вернёмся к теме обсуждения.


Предлагаю закрыть тему непонимания со всех сторон и просто перечитать http://forum.vingrad.ru/index.php?showtopic=273012&view=findpost&p=1969750 столько раз, сколько необходимо, чтобы он для вас стал мантрой. Разумеется есть всякие ситуации, но описанные solenko три пункта - это заветы, которым необходимо следовать, потому, что это логично, это правильно.
Не думаю, что тут можно что-то еще добавить.

Добавлено @ 15:47
Цитата(nerezus @  18.9.2009,  13:58 Найти цитируемый пост)
Я тоже. И я с тобой согласен. Причем это мнение разделяют уважаемые члены phpclub.
Но у парней из Зенда другое мнение - попробуй сдать тест на ZCE. Я завалил разделы Security и PHP4(все остальное на Excellent). Security завалена по этой причине. Когда же стал читать их ман, то увидел, что у нас просто разница в терминологии, и обработку по непонятным причинам они называют фильтрацией. 

Я за понимание. Когда я приезжаю на PHPConf, где могу пообщаться с гуру интернет-промышленности, у меня с ними не возникает непонимания из-за различия в терминологии, потому, что я не считаю, что в нашем ремесле дозволены подобные вольности. Я знаю как правильно, пусть и не всегда знаю почему именно, но это неоспоримо. 
Это что касается нас.
Парни из Зенда, у них менталитет другой, язык другой, сообщество отличается. Но это уже другой вопрос.


Автор: MoLeX 18.9.2009, 18:12

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)