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

Форум PHP

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

 

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

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

тема: Проверка скрипта на дыры
 
 автор: JIEXA   (13.02.2005 в 16:49)   письмо автору
 
 

Вообщем пользователь вводит имя, емаил и текст. Это всё обрабатывается таким скриптом:
<?php
if(empty($id))
{
        include
"includes/header.php";
        echo
"<br><br><center><b>Ошибка!</b><br>Обратитесь по <a href=\"mailto:php-jiexa@mail.ru\">этому</a> email'у.</center>";
        include 
"includes/footer.php";
        exit();
}
if(
$id!="")
{
        if(
strspn($id,"0123456789") != strlen($id))
        {
                include
"includes/header.php";
                echo
"<br><br><center><b>Ты тупой \"хакер\"</b></center>";
                include 
"includes/footer.php";
                exit();
        }
}
if (empty(
$name)){
        include
"includes/header.php";
        echo
"<br><br><center><b>Введите ваше имя!</b></center>";
        include 
"includes/footer.php";
        exit();
}
if (
$email != "")
{
        if (!
preg_match("/[0-9a-z_]+@[0-9a-z_^\.]+\.[a-z]{2,3}/i"$email))
        {
          include
"includes/header.php";
          print
"<br><br><center><b>Неверно введен е-mail. Введите e-mail в виде <i>email@email.ru</i></b></center>\n";
          include 
"includes/footer.php";
        exit();
        }
}

if (empty(
$c_text)){
        include
"includes/header.php";
        echo
"<br><br><center><b>Вы забыли ввести текст комментариев!</b></center>";
        include 
"includes/footer.php";
        exit();
}
if(
strlen($name) > "40")
{
        include
"includes/header.php";
        echo 
"<br><br><center><b>Ваше имя привышает 40 символов!</b></center>";
        include 
"includes/footer.php";
        exit;
}
if(
strlen($email) > "40")
{
        include
"includes/header.php";
        echo 
"<br><br><center><b>Ваш e-mail привышает 40 символов!</b></center>";
        include 
"includes/footer.php";
        exit;
}
if(
strlen($c_text) > "5000")
{
        include
"includes/header.php";
        echo 
"<br><br><center><b>Текст комментариев привышает 5000 символов!</b></center>";
        include 
"includes/footer.php";
        exit;
}
$name=htmlspecialchars($name);
if (!
get_magic_quotes_gpc())
{
        
$name mysql_escape_string($name);
        
$email mysql_escape_string($email);
        
$c_text mysql_escape_string($c_text);
}
$query "INSERT INTO articles_commentaries (cid, id, name, email, c_text, date) values (NULL, '$id', '$name', '$email', '$c_text', now())";
mysql_query($query$db);
if(
$save!="")
{
          
setcookie("comm_name"$nametime() + 3600*24*14);
          if(
$email!="")
          {
                  
setcookie("comm_email"$emailtime() + 3600*24*14);
          }
}
header("Location: ".$siteurl."/articles/$id.html");
?>

Есть ли здесь дыры в безопасности?

   
 
 автор: cheops   (13.02.2005 в 17:01)   письмо автору
 
   для: JIEXA   (13.02.2005 в 16:49)
 

Вроде ничего криминального нет... а как потом используется значение из cookie?

   
 
 автор: JIEXA   (13.02.2005 в 19:06)   письмо автору
 
   для: cheops   (13.02.2005 в 17:01)
 

Значения из cookie потом вставляются в форму добовления комментарием, чтобы 100 раз не вводить имя и е-маил

   
 
 автор: Никоза   (13.02.2005 в 19:24)
 
   для: JIEXA   (13.02.2005 в 19:06)
 

В самом верху, наверное, стоит написать

<?
sleep(1);
// Пауза 1 секунда, чтобы он не смог применить никакие аппаратные средства перебора и т.д.

   
 
 автор: JIEXA   (13.02.2005 в 19:39)   письмо автору
 
   для: Никоза   (13.02.2005 в 19:24)
 

спасибо напишу :)

   
 
 автор: XPraptor   (14.02.2005 в 14:21)   письмо автору
 
   для: JIEXA   (13.02.2005 в 19:39)
 

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

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

test@mail.com; print "<SCRIPT language='JavaScript'> self.open('', 'hak'); </SCRIPT>";

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

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

   
 
 автор: Никоза   (14.02.2005 в 16:56)
 
   для: XPraptor   (14.02.2005 в 14:21)
 

Да уж... Очень наглядно продемонстрировано.
Надобно вот так:
$text=strtr($text,"?<>$=+%&^([{", "###D########");
Всё "в кавычках слева" меняем на решетки. (Окромя доллара - там ставим D, пригодится :-)))

   
 
 автор: imi   (26.02.2005 в 17:03)   письмо автору
 
   для: Никоза   (14.02.2005 в 16:56)
 

Для мыла это пойдет, а для обычного текста? Или запретить, например, на форуме знак вопроса?

   
 
 автор: Никоза   (26.02.2005 в 18:27)
 
   для: imi   (26.02.2005 в 17:03)
 

Так запретить знак вопроса вроде точно также...
$text=strtr($text,"?", "#"); // Меняем его на решетку
Наверное, Вам это очень нужно - запретить знак вопроса...? Правильно - не фиг задавать вопросы...

   
 
 автор: imi   (26.02.2005 в 20:12)   письмо автору
 
   для: Никоза   (26.02.2005 в 18:27)
 

хех :)
видимо, я неправильно выразился.
Мне как раз-таки надо, чтобы все символы перечисленные ранее

$text=strtr($text,"?<>$=+%&^([{", "###D########");

не заменялись на решетки, а оставались самими собой... Но при этом не образовывалась дыра, описанная XPraptor'ом

   
 
 автор: Никоза   (26.02.2005 в 23:33)
 
   для: imi   (26.02.2005 в 20:12)
 

Лучше всего Вам скачать отсюда учебник php 5, Так вот, там есть большинство функций, в том числе и эта. Всё написано чётко и ясно, всегда ( почти всегда, вернее!!! Лучше бы было всегда... ) с примерами Я просто не помню её - не практиковал с ней. Но она там есть.
Скачивать в разделе загрузки.
[поправлено модератором]

   
 
 автор: cheops   (27.02.2005 в 11:57)   письмо автору
 
   для: imi   (26.02.2005 в 20:12)
 

В этом случае необходимо воспользоваться функцией htmlspecialchars, которая преобразует спец-символы в их HTML-эквиваленты
<?php
$text 
htmlspecialchars($text);
?>


http://www.softtime.ru/dic/id_dic=28&id_group=1

   
 
 автор: imi   (27.02.2005 в 13:47)   письмо автору
 
   для: cheops   (27.02.2005 в 11:57)
 

Господа!
Вы, видно, запутать меня хотите :-)
Ведь в приведенном выше листинге есть htmlspecialchars....
В чем же тогда дырка "от XPraptor'а"?
Каких символов не хвататет (или какие символы не пропустил форум) в его посте? Ибо то, что видно, ничего страшного из себя не представляет... Все кавычки экранируются, все опасные символы обрабатываются htmlspecialchars. Покажите, где же дырка?

   
 
 автор: imi   (27.02.2005 в 13:50)   письмо автору
 
   для: imi   (27.02.2005 в 13:47)
 

Пардон, только $name c помощью него обрабатывается.... Но в данном случае это ничего не меняет.... Каких-то символов у XPraptor'a явно не хватает....

   
 
 автор: cheops   (27.02.2005 в 14:06)   письмо автору
 
   для: imi   (27.02.2005 в 13:47)
 

e-mail, кстати лучше защитить вот таким регулярным выражением http://www.softtime.ru/forum/read.php?id_forum=1&id_theme=2024
<?php
if (!preg_match("/^[-0-9a-z_]+@[-0-9a-z_^\.]+\.[a-z]{2,3}$/i"$email))
{
  echo 
"Неправильно введён e-mail";
}
?>


А вот мне ещё чего не нравится, да $name обрабатывается функцией htmlspecialchars, а $c_text нет :(

   
 
 автор: imi   (27.02.2005 в 14:15)   письмо автору
 
   для: cheops   (27.02.2005 в 14:06)
 

Спасибо за ответы.
Но один вопрос остался-таки неотвеченным... Каких символов не хватает в посте ХРраптора? Где дыра?

   
 
 автор: cheops   (27.02.2005 в 14:50)   письмо автору
 
   для: imi   (27.02.2005 в 14:15)
 

Приведённое выше постом регулярное выражение не допустит уже такого взлома, так как в нём явно указаны границы слова, после e-mail уже что-то написать не получится.

   
 
 автор: imi   (27.02.2005 в 14:52)   письмо автору
 
   для: cheops   (27.02.2005 в 14:50)
 

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

   
 
 автор: Atom   (27.02.2005 в 15:23)   письмо автору
 
   для: imi   (27.02.2005 в 14:52)
 

Дыра в том, что если человек введет имеил, и после имейла свой код, то скрипт пропустит этот код.

   
 
 автор: imi   (27.02.2005 в 16:08)   письмо автору
 
   для: Atom   (27.02.2005 в 15:23)
 

Вопрос - какой код? Тот код, который показал ХРраптор - безопасен.

   
 
 автор: Atom   (27.02.2005 в 16:14)   письмо автору
 
   для: imi   (27.02.2005 в 16:08)
 

Мдя....
А тот код, который не показал Раптор, но покажет другой, менее благонастроенный человек опасен.
К примеру
print system("что-то плохое");
очень опасно.

   
 
 автор: imi   (27.02.2005 в 17:38)   письмо автору
 
   для: Atom   (27.02.2005 в 16:14)
 

Доктор, я, кажется, разговариваю на другом языке :)))
Итак, берем укороченную версию скрипта, адаптированного для тестов:

$text= (isset($HTTP_POST_VARS['text']))? $HTTP_POST_VARS['text']:'';
if (!get_magic_quotes_gpc())
{
    $text = mysql_escape_string($text);
}
echo $text;
echo '<form method="post"><input name="text"><input type="submit"></form>';

Теперь выделяем из поста ХРраптора предлагаемый кусок кода и вставляем в форму, жмем кнопку.
Что происходит? что-то экстраординарное? Выдается test@mail.com; print \"\";
т.е. не выполнилась ни инструкция PHP, ни javascript.
Я чего-то не понимаю?
P.S. Приятно удивлен вашим терпением :) На других форумах давно бы уже облили грязью...

   
 
 автор: Atom   (27.02.2005 в 19:01)   письмо автору
 
   для: imi   (27.02.2005 в 17:38)
 

Ой, точно, я код невнимательно читал.

Кст, вопрос к Храптору.
Конкретизируйте, пожалуйста, в каких случаях mysql_escape_string не спасает от sql инъекций?

   
 
 автор: JIEXA   (05.03.2005 в 18:51)   письмо автору
 
   для: Atom   (27.02.2005 в 19:01)
 

Я тут немного переделал:

<?php
chdir
("../");
include
"includes/config.php";
include
"includes/utils.php";
$url_host parse_url($HTTP_REFERER );
$referer=$url_host[host];
$referer=str_replace("www."""$referer);
$h_referer="http://".$referer;
if(
$h_referer!=$siteurl)
{
        include
"includes/header.php";
        print
"<br><br><center><b>Зачем тебе ломать этот сайт? Вали отсюда!</b></center>";
        include
"includes/footer.php";
        exit();
}
$name=trim($_POST['name']);
$email=trim($_POST['email']);
$c_text=trim($_POST['c_text']);
$id=trim($_POST['id']);
if(empty(
$id)) # Если неопределена переменная id, то форма отправлена с чужого сайта...
{
        include
"includes/header.php";
        echo
"<br><br><center>Хакер? ха ха...</center>";
        include 
"includes/footer.php";
        exit();
}
if(
$id!="")
{
        if(
strspn($id,"0123456789") != strlen($id)) # Если переменная id содержит, что-то кроме цифор
        
{
                include
"includes/header.php";
                echo
"<br><br><center>Ой, что-то неполучилось взломать сайт :)</center>";
                include 
"includes/footer.php";
                exit();
        }
}
if (empty(
$name)){ # Ввёл ли пользователь имя?
        
include"includes/header.php";
        echo
"<br><br><center><b>Введите ваше имя!</b></center>";
        include 
"includes/footer.php";
        exit();
}
if(
strlen($name) > "40"# Оно больше 40 символов?
{
        include
"includes/header.php";
        echo 
"<br><br><center><b>Ваше имя привышает 40 символов!</b></center>";
        include 
"includes/footer.php";
        exit;
}
if(
preg_match("/<.*?(script|object|iframe|applet|meta|style|form).*?>/"$name)) # Хочет хакнуть сайт через скрипты?
{
        include
"includes/header.php";
        print
"<br><br><center>Хакер? ха ха...</center>";
        include
"includes/footer.php";
        exit();
}
if (
preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/",$name)) {
        include
"includes/header.php";
        echo 
"<br><br><center><b>В имени можно использовать только буквы русского и латинского алфавита, цифры, знак _ и пробел.</b></center>";
        include
"includes/footer.php";
        exit;
}
if (empty(
$c_text)){ # Ввёл ли пользователь текст комментария
        
include"includes/header.php";
        echo
"<br><br><center><b>Вы забыли ввести текст комментариев!</b></center>";
        include 
"includes/footer.php";
        exit();
}
if (
$email != ""# Правильно ли ввёл пользователь e-mail
{
        if (
preg_match("/[^(\w)|(\@)|(\.)]/",$email))
        {
                include
"includes/header.php";
                print
"<br><br><center><b>Неверно введен е-mail. Введите e-mail в виде <i>email@email.ru</i></b></center>\n";
                include 
"includes/footer.php";
                exit;
        }
}
if(
strlen($email) > "40"# Он больше 40 символов?
{
        include
"includes/header.php";
        echo 
"<br><br><center><b>Ваш e-mail привышает 40 символов!</b></center>";
        include 
"includes/footer.php";
        exit;
}
if(
strlen($c_text) > "5000"# Текст комментария привышает 5000 символов?
{
        include
"includes/header.php";
        echo 
"<br><br><center><b>Текст комментариев привышает 5000 символов!</b></center>";
        include
"includes/footer.php";
        exit;
}
/* Обработаем имя, e-mail и текст комментария */
$name=htmlspecialchars(addslashes($name));
$email=htmlspecialchars(addslashes($email));
$c_text=addslashes($c_text);
if (!
get_magic_quotes_gpc())
{
        
$name mysql_escape_string($name);
        
$email mysql_escape_string($email);
        
$c_text mysql_escape_string($c_text);
}
mysql_query("UPDATE news SET comm=comm+1 WHERE id='".$id."'");
$query "INSERT INTO news_commentaries (cid, id, name, email, c_text, date) values (NULL, '".$id."', '".$name."', '".$email."', '".$c_text."', now())";
mysql_query($query$db);
if(
$save!="")
{
          
setcookie("comm_name"$nametime() + 3600*24*14);
          if(
$email!="")
          {
                  
setcookie("comm_email"$emailtime() + 3600*24*14);
          }
}
header("Location: ".$siteurl."/news/".$id.".html");
?>

P.S. c_text обрабатывается htmlspecialchars толькл при выводе в браузер )))

   
 
 автор: cheops   (27.02.2005 в 16:53)   письмо автору
 
   для: imi   (27.02.2005 в 16:08)
 

Обычно средствами JavaScript вытаскивают конфидициальную информацию из cookie (логины, пароли) и отправляют её на хост злоумышленника.

   
Rambler's Top100
вверх

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