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

Форум PHP

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

 

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

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

тема: Безопасное программирование на PHP (отзыв)
 
 автор: antf   (31.01.2005 в 16:58)   письмо автору
 
 

Здравствуйте. Прочитал несколько раз эту статью, и могу сказать, что она мне очень понравилась. Особенно хотелось бы отметить актуальность темы, рациональность построения, доступный и одновременно сжатый язык, несложные примеры, наличие ссылок на более подробные источники и ценные рекомендации в конце. Надо сказать, что какие-то методы защиты я уже использовал, с некоторыми только познакомился, а другие еще предстоит усвоить в дальнейшем. В любом случае данный материал может стать отправной точкой для еще более глубокого изучения проблемы безопасности. Могу сказать, что это не первый найденный мною материал по теме: некоторые статьи страдают отсутствием целостности, другие - ненаглядными и очень громоздкими примерами, третьи кишат орфографическими и грамматическими ошибками (хотя я и сам нередко допускаю пунктуационные ошибки (и не только :), поскольку имею дело с иностранными языками, и ни в каком из них нет таких жестких правил расстановки знаков препинания; к хорошему привыкаешь :). Эта статья лишена всех перечисленных выше недостатков, поэтому она стала первой статьей по теме безопасность, которую я оценил. Хочу выразить свою благодарность авторам статьи".

http://www.softtime.ru/info/articlephp.php?id_article=35

PS Не является ли очепяткой двойное echo в этой строке?
<input type=hidden name=session_id value=<?php <i>echo echo </i> session_id();?>>

   
 
 автор: cheops (из ННГУ)   (31.01.2005 в 17:14)
 
   для: antf   (31.01.2005 в 16:58)
 

Спасибо за добрый отзыв, опечатку сегодня же устраним.

   
 
 автор: Atom   (31.01.2005 в 18:51)   письмо автору
 
   для: cheops (из ННГУ)   (31.01.2005 в 17:14)
 

Еще вопросик насчет этой статьи.
Касаемо этого пункта:

<?php 
  
// Устанавливаем соединение с базой данных 
  
include "config.php"
  
// Осуществляем соответствия имени паролю 
  
$query "SELECT * FROM users 
            WHERE name = '
$_POST[name]' AND 
                  pass = '
$_POST[pass]'"
  
$usr mysql_query($query); 
  if(!
$usr) exit("Ошибка в SQL-запросе"); 
  if(
mysql_num_rows($usr)>0
  { 
    
// Вход в защищённую область сайта 
  

?>
Ломается это таким методом:
123' AND 1=1


А если провести авторизацию так:

<?php 
  
// Устанавливаем соединение с базой данных 
  
include "config.php"
  
// Осуществляем соответствия имени паролю 
  
$query mysql_fetch_array(mysql_query("SELECT * FROM users 
            WHERE name = '
$_POST[name]' AND 
                  pass = '
$_POST[pass]'"));
   if (
$_POST['pass'] == $query['pass'])
  {
    
// Вход в защищённую область сайта 
  
}
  else exit();
?>


Тогда скрипт не уязвим подобной атаке?

   
 
 автор: Atom   (31.01.2005 в 18:58)   письмо автору
 
   для: Atom   (31.01.2005 в 18:51)
 

Да, и еще вариант

<?
$get 
mysql_fetch_array(mysql_query("select login, password from users where login='$login'"));
if (
$get['password'] == $password)
{
 
// Защищенная зона
}
else { exit(); }
?>

   
 
 автор: cheops   (31.01.2005 в 22:25)   письмо автору
 
   для: Atom   (31.01.2005 в 18:58)
 

Нет такой способ не позволит обезопасить базу... лучше заменять прямые кавычки ' - обратными (не могу показать, так как на форуме это реализовано в движке :) - в общем она находится под буквой ё.

   
 
 автор: 1dt.w0lf   (31.01.2005 в 22:53)   письмо автору
 
   для: cheops   (31.01.2005 в 22:25)
 

Замена одинарных кавычек на обратные (как это реализовано в данном форуме) не является полноценной защитой от атак sql injection в случаях когда в php.ini отключены magic_quotes

   
 
 автор: cheops   (31.01.2005 в 23:04)   письмо автору
 
   для: 1dt.w0lf   (31.01.2005 в 22:53)
 

Хм... ну можно прибегать к явному экранированию кавычек... Кстати, почему, я что-то сообразить не могу если у нас в одинарные кавычки заключены обратные, как можно провернуть SQL-инъекцию?

   
 
 автор: 1dt.w0lf   (31.01.2005 в 23:17)   письмо автору
 
   для: cheops   (31.01.2005 в 23:04)
 

Вы имеете доступ к почте softtime@softtime.ru ? Просто туда я отправил описание некоторых ошибок. Если Вам интересно каким образом можно получить информацию из базы данных при таких условиях то можно пообщаться в аське. Стучите 100232001.

   
 
 автор: Atom   (31.01.2005 в 23:27)   письмо автору
 
   для: 1dt.w0lf   (31.01.2005 в 23:17)
 

Тоесть заменить кавычки и все? А что еще? Как польностью обезопасить базу?

И насчет magic quotes. Как узнать, включены они на хостинге или нет?

   
 
 автор: cheops   (01.02.2005 в 00:27)   письмо автору
 
   для: Atom   (31.01.2005 в 23:27)
 

Так как беседа с 1dt.w0lf прошла приватно, сухой остаток сообщу здесь. Узнать включены ли magic quotes можно при помощи функции get_magic_quotes_gpc(). В мануале предлагается следующее её использование
<?php
if (!get_magic_quotes_gpc()) {
    
$lastname addslashes($_POST['lastname']);
} else {
    
$lastname $_POST['lastname'];
}
?>

   
 
 автор: Atom   (01.02.2005 в 01:03)   письмо автору
 
   для: cheops   (01.02.2005 в 00:27)
 

Тоесть если magic_quotes включены, то для безопасности надо только запросы в обратные кавычки помещать, а если выключенны, то addsleshes?
А что дает addslashes?

   
 
 автор: cheops   (01.02.2005 в 02:39)   письмо автору
 
   для: Atom   (01.02.2005 в 01:03)
 

Если magic_quotes включены как у нас на сайте, то все спец-символы экранируются автоматически, если это не так это нужно сделать самостоятельно при помощи функции addslashes() http://www.softtime.ru/dic/id_dic=12&id_group=1, а ещё лучше mysql_escape_string() http://www.softtime.ru/dic/id_dic=96&id_group=2
Кстати, вот несколько ссылок, которые рекомендуется почитать всем кто работает с MySQL (очень хорошее описание SQL-инъекций и методов защиты)
http://www.securitylab.ru/45438.html
http://www.securitylab.ru/49424.html

PS Эти ссылки добавлены в статью http://www.softtime.ru/info/articlephp.php?id_article=35

   
 
 автор: localGhost   (01.02.2005 в 05:01)   письмо автору
 
   для: cheops   (01.02.2005 в 02:39)
 

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

<?
// $_SESSION['user_name'] - переменная в которой храниться имя пользователя
// если данный были введены в форму авторизации то они записываються
// в эту переменную. $_SESSION['user_pass'] - то же самое, только пароль.
//
$sql_name $_SESSION['user_name'];
// (двух одинаковых имен пользователя в базе не существует)
$result mysql_query ("SELECT pass FROM accbd WHERE set_user='$sql_name'");
$row mysql_fetch_array ($result);
if (
$row == NULL) {
   
// если пользователя с указанным именем нет в базе то не пускаем
} else {
   
// если пользователь найден в базе то проверяем далее:
   
$real_pass $row["pass"];
   
// если пароль для указанного пользователя не верен то:
   
if ($real_pass != $_SESSION['user_pass']) {
       
// то не пускаем!
   
}
}
// если указанные имя и пароль оказались верны, то пускаем в закрытую часть
//
// занчения имя и пароль записываються шифрованными в сессию
// и в дальнейшем проверяються каждый раз как загружеться новая страница.
// В случае удачной проверки пользователь считаеться авторизованным.
?>


покритикуйте пжста!

   
 
 автор: cheops   (01.02.2005 в 14:01)   письмо автору
 
   для: localGhost   (01.02.2005 в 05:01)
 

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

   
 
 автор: Atom   (01.02.2005 в 14:24)   письмо автору
 
   для: cheops   (01.02.2005 в 14:01)
 

А насчет универсальных прав.. Там таких нет =) Управление осуществляется через админку, защищенную htpasswd

Блин, я окончательно запутался.
У меня включены magic_quotes. При запросе я ставлю обр. кавычки, и нифига. С обычными работает скрипт, а с обратными нет.

   
 
 автор: cheops   (01.02.2005 в 14:33)   письмо автору
 
   для: Atom   (01.02.2005 в 14:24)
 

А куда вы ставите обратные кавычки? Здесь имеется ввиду замена прямых кавычек в тексте
O'REILLY

на обратные перед помещением текста в базу данных

   
 
 автор: Atom   (01.02.2005 в 14:54)   письмо автору
 
   для: cheops   (01.02.2005 в 14:33)
 

Я совсем о другом думал.
Я переменную в запросе в кавычки помещал.
Так, оказывается на сервере magic_quotes выключен, значит addsleshes.
А эту функцию можно в самом запросе проверять?
Тоесть SELECT * from table where login='".addsleshes($login)."' ?

   
 
 автор: cheops   (01.02.2005 в 22:15)   письмо автору
 
   для: Atom   (01.02.2005 в 14:54)
 

Да эту функцию можно и так использовать.

   
 
 автор: cheops   (01.02.2005 в 00:02)   письмо автору
 
   для: 1dt.w0lf   (31.01.2005 в 23:17)
 

Спасибо за помощь, почту с softtime@softtime.ru обрабатываю не я, но все ваши письма будут обязательно мне переправлены.

   
 
 автор: Artem S.   (01.02.2005 в 05:50)   письмо автору
 
   для: Atom   (31.01.2005 в 18:58)
 

2Atom
Все тоже самое. Тут еще надо смотреть конкретный случай. Если есть регистрация на сайте обычных пользователей, а по такому признаку приводиться авторизация админа, то можно войти по своим логином в админку...

   
 
 автор: Artem S.   (01.02.2005 в 05:47)   письмо автору
 
   для: Atom   (31.01.2005 в 18:51)
 

2Atom
Тут есть свои тонкости. А что если я не укажу пароля вообще, а имя задам несуществующие? мы получим:
$_POST['pass'] = '';
$query['pass'] = '';
$_POST['pass'] == $query['pass']

   
 
 автор: localGhost   (01.02.2005 в 05:55)   письмо автору
 
   для: Artem S.   (01.02.2005 в 05:47)
 

.

   
 
 автор: Atom   (01.02.2005 в 10:22)   письмо автору
 
   для: Artem S.   (01.02.2005 в 05:47)
 

2Artem S.
Если ты не укажешь пароля, то он не начнет выполнять скрипт. Я там не полностью расписал просто. Тоесть if (isset($_POST['login']) && isset($_POST['password'])) {
//authorise script
}
elseif(empty($_POST['login'] || empty($_POST['password']))
{
//input form
}

   
 
 автор: 1dt.w0lf   (01.02.2005 в 12:45)   письмо автору
 
   для: Atom   (01.02.2005 в 10:22)
 

---
Если ты не укажешь пароля, то он не начнет выполнять скрипт. Я там не полностью расписал просто. Тоесть if (isset($_POST['login']) && isset($_POST['password'])) {
//authorise script
}
elseif(empty($_POST['login'] || empty($_POST['password']))
{
//input form
}
---

1. isset еще не означает что переменная не пуста, попробуй просто передать пустую переменную
2. зачем elseif? else вполне достаточно.

   
 
 автор: Artem S.   (02.02.2005 в 07:09)   письмо автору
 
   для: antf   (31.01.2005 в 16:58)
 

Не нужно все внимание обострять лишь на авторизации. Скорее всего, в скрипте будут и другие "дыры", через которые можно получить спец. права. Нужно смотреть весь код, и внимательно писать sql запрос и т.д.
Просто следуйте рекомендациям и проблем будит меньше.

   
 
 автор: XPraptor   (02.02.2005 в 12:48)   письмо автору
 
   для: Artem S.   (02.02.2005 в 07:09)
 

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

$login=$_POST["snd_login"];
$pass=$_POST["snd_pass"];
$snd_hash=MD5($login . $pass);
$rez=mysql_query("SELECT usr_hash FROM Users WHERE usr_hash='" . $snd_hash . "');


И все. А при регистрации в базу пишу только пароль и хэш логин пароль. Можно и пароль не писать. но я всегда делаю сервис отправки забытого пароля, поэтому еще пароль храню, а логин вообще никуда не пишу, только хэш связки логин-пароль.

   
 
 автор: 1dt.w0lf   (02.02.2005 в 16:25)   письмо автору
 
   для: XPraptor   (02.02.2005 в 12:48)
 

1. Скорость... все упирается в скорость работы. Твоя функция md5() будет заметно тормозить особенно при большом количестве юзеров.
2. А пароль то в базу записывается? Получается что его проверять все равно придется перед помещением в запрос при регистрации.
3. Одной авторизацией дело не ограничивается. Или ты все данные в базе шифровать собрался?

   
 
 автор: XPraptor   (03.02.2005 в 16:07)   письмо автору
 
   для: 1dt.w0lf   (02.02.2005 в 16:25)
 

На счет скорости ты зря! Шифр 24 букв абсолютно не занимает время.
Все данные шифровать не надо, я показал пример что нельзя сделать SQL инъекцию при таком методе проверке логина и пароля. И в других местах приема данных тоже надо сначала присвоить их переменным, потом если надо отфильтровать, а только потом подставлять в запрос.

   
Rambler's Top100
вверх

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