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

Форум MySQL

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

 

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

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

тема: Магические кавычки
 
 автор: Саня   (27.09.2009 в 21:54)   письмо автору
 
 

Не успел я отправить сообщение в тему, как cheops закрыл её.

@Commander:
Вы, кажется, не понимаете зачем вообще нужно экранирование.
Язык программирования умеет работать со строками. Строка — это набор символов, заключённые в одинарные или в двойные кавычки (я сейчас про РНР). А что если понадобится записать кавычку в строке? По правилам языка строку
<?
'Tim O'Reilly';
интерпретатор разберёт как "Tim O", а всё остальное окажется ошибкой синтаксиса. Другое дело когда мы пишем
<?
'Tim O\'Reilly'
Интерпретатор воспримет \' не как окончание строки, а как кавычку внутри строки. В итоге синтаксис не нарушен и всё идёт как надо. Это и называется экранированием.

Грубо говоря, описанное выше можно принять как первопричину таких уязвимостей как code-injection и sql-injection.

А теперь рассмотрим составление sql-запроса:
<?
mysql_query
("INSERT INTO `table` VALUES('{$_POST['name']}', '{$_POST['message']}')";

Ошибка очевидна. Если я в форме напишу name: Tim O'Reilly, то весь запрос примет такую форму:
INSERT INTO `table` VALUES('Tim O'Reilly', 'Some message')
Сразу понятно, что кавычку после O, mysql воспримет как окончание строки и дальнейшее вызовет, как ни странно, ошибку синтаксиса.... а если я напишу в поле с именем name
Tim O', ''); DROP TABLE `table`; -- 

То окончательный sql-запрос будет выглядеть так:
INSERT INTO `table` VALUES('Tim O', ''); DROP TABLE `table`; -- , 'Some message')

Всё, что следует от "--[пробел]" до конца строки интерпретируется как комментарий.
Вот так вот.

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

  Ответить  
 
 автор: Рома   (27.09.2009 в 22:54)   письмо автору
 
   для: Саня   (27.09.2009 в 21:54)
 

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

  Ответить  
 
 автор: ride   (27.09.2009 в 23:02)   письмо автору
 
   для: Саня   (27.09.2009 в 21:54)
 

>> INSERT INTO `table` VALUES('Tim O', ''); DROP TABLE `table`;
у вас обе эти команды выполняются?

  Ответить  
 
 автор: Trianon   (27.09.2009 в 23:21)   письмо автору
 
   для: ride   (27.09.2009 в 23:02)
 

нет.
Но и в пределах одного запроса тоже можно дров наломать.

  Ответить  
 
 автор: Рома   (02.10.2009 в 11:48)   письмо автору
 
   для: Trianon   (27.09.2009 в 23:21)
 

в продолжение предыдущей темы

вот ваша функция
function rec_stripslashes($mixed) 

    if( is_array($mixed) ) 
    { 
        return array_map('rec_stripslashes', $mixed); 
    } 
    else 
    { 
        return stripslashes($mixed); 
    } 


вы написали, что нужно добавить обработку ключей.
пошел вот таким путем, чтоб извлечь ключи, но вот обработать их чето ума не хватает.
function rec_stripslashes(&$arr)
 {
 foreach($arr as $key=>$value)
  {
   if(is_array($value))
   {
        $arr[$key] = rec_stripslashes($value);        
   }
   else
   {
         $arr[$key] = stripslashes($value);
   }
  }
 }

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

  Ответить  
 
 автор: cheops   (02.10.2009 в 11:58)   письмо автору
 
   для: Рома   (02.10.2009 в 11:48)
 

Это в продолжение темы "Магические кавычки" или вы ошиблись темой? Если да, то при этом подходе придется уничтожать элементы суперглобальных массивов с магическими кавычками и создавать новые - без них.

  Ответить  
 
 автор: Рома   (02.10.2009 в 12:09)   письмо автору
 
   для: cheops   (02.10.2009 в 11:58)
 

Это в продолжение темы "Обратная mysql_escape_string() функция".

чето я не понял, раз этот подход правильный,
function rec_stripslashes($mixed) 

    if( is_array($mixed) ) 
    { 
        return array_map('rec_stripslashes', $mixed); 
    } 
    else 
    { 
        return stripslashes($mixed); 
    } 

if( get_magic_quotes_gpc() ) 

    $_GET = rec_stripslashes( $_GET ); 
    $_POST = rec_stripslashes( $_POST ); 
}

разве неправильно будет дополнить эту ф-ию обработкой ключей?

  Ответить  
 
 автор: cheops   (02.10.2009 в 12:14)   письмо автору
 
   для: Рома   (02.10.2009 в 12:09)
 

Да, правильно, магические кавычки и на них влияют. Придется вшивать следующую логику
<?php
  $keynew 
stripslashes($key);
  if(
$keynew != $key)
  {
    
$arr[$keynew] = $arr[$key];
    unset(
$arr[$key]);
  }

  Ответить  
 
 автор: Рома   (02.10.2009 в 14:13)   письмо автору
 
   для: cheops   (02.10.2009 в 12:14)
 

чето мне эта логика не нравиться, она возвращает новый ключ, а если сделать чтоб возвращало старый, вот так?

<?php
  $keynew 
stripslashes($key);
  if(
$keynew != $key)
  {
    unset(
$arr[$key]);
    
$arr[$key] = $arr[$keynew];    
  } 

  Ответить  
 
 автор: cheops   (02.10.2009 в 14:18)   письмо автору
 
   для: Рома   (02.10.2009 в 14:13)
 

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

  Ответить  
 
 автор: Рома   (02.10.2009 в 14:23)   письмо автору
 
   для: cheops   (02.10.2009 в 14:18)
 

.

  Ответить  
 
 автор: Рома   (02.10.2009 в 14:30)   письмо автору
 
   для: Рома   (02.10.2009 в 14:23)
 

нет, так не работает, я уже сам убедился

  Ответить  
 
 автор: cheops   (02.10.2009 в 14:30)   письмо автору
 
   для: Рома   (02.10.2009 в 14:23)
 

Нет, так как вы уничтожаете сначала элемент массива со старым ключом
unset($mixed[$key]);

а потом присваиваете ему элемент с новым ключом (которого, кстати говоря, ещё и нет).
$mixed[$key] = $mixed[$keynew];

Не понятно, также, какие цели преследует код
   return $mixed[$key]; 
   $value = stripslashes($value); 
   return $mixed[$value];

У вас срабатывает первый return, до второго даже дело не доходит.

PS Элемент, который удаляете при помощи unset() нужно обязательно сохранить. Получать элемент со старым ключом не имеет никакого смысла - старый ключ содержит результаты работы магических кавычек - от этого ключа можно только избавиться. Переименовать его нельзя, так как переименование состоит в том, что вы его уничтожаете и вместо него заводите новый ключ.

  Ответить  
 
 автор: Рома   (02.10.2009 в 14:37)   письмо автору
 
   для: cheops   (02.10.2009 в 14:30)
 

.

  Ответить  
 
 автор: cheops   (02.10.2009 в 14:59)   письмо автору
 
   для: Рома   (02.10.2009 в 14:37)
 

>return в функции может быть только один?
Нет, почему, может быть и несколько, но срабатывает только один.

  Ответить  
 
 автор: cheops   (02.10.2009 в 15:03)   письмо автору
 
   для: cheops   (02.10.2009 в 14:59)
 

Почему, можно и объединить, только использовать какой-то такой код
<?php
  
function rec_stripslashes($mixed
  { 
    if(
is_array($mixed)) 
    { 
      
$mixed array_map('rec_stripslashes'$mixed); 
      foreach(
$mixed as $key => $value
      { 
        
$keynew stripslashes($key); 
        if(
$keynew != $key
        { 
          
$mixed[$keynew] = $mixed[$key]; 
          unset(
$mixed[$key]); 
        } 
      }
      return 
$mixed
    } 
    else 
    { 
      return 
stripslashes($mixed); 
    } 
  }
?>

  Ответить  
 
 автор: Рома   (02.10.2009 в 15:31)   письмо автору
 
   для: cheops   (02.10.2009 в 15:03)
 

Спасибо, никогда бы не пришло в голову так написать.
<?php
      $mixed 
array_map('rec_stripslashes'$mixed); 
      foreach(
$mixed as $key => $value
      {
      
//
      
}
Думал, что $value в цикле нужно обрабатывать, и никак иначе.

  Ответить  
 
 автор: Trianon   (02.10.2009 в 15:42)   письмо автору
 
   для: cheops   (02.10.2009 в 15:03)
 

>$mixed[$keynew] = $mixed[$key];

Не получится ли тут повторной обработки уже обработанных элементов?
Мне кажется, надежнее будет весь массив заново построить, нежели вбивать элементы в тот, что прямо сейчас раскручивает итератор foreach

      $mixed = array_map('rec_stripslashes', $mixed); 
      $res = array();
      foreach($mixed as $key => $value) 
        $res[stripslashes($key)] = $value; 
      $mixed = res;

  Ответить  
 
 автор: Саня   (28.09.2009 в 06:39)   письмо автору
 
   для: ride   (27.09.2009 в 23:02)
 

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

  Ответить  
 
 автор: Commander   (29.09.2009 в 19:19)   письмо автору
 
   для: Саня   (27.09.2009 в 21:54)
 

Это мне и так ясно, вопрос был в том, как проще всего обойти все эти неприятности. Да и вообще, алгоритм был у меня в голове, главное было, как убрать экранирующие слэши. Спасибо cheops'у, подсказал.

Про sql-инъекции я хорошо знаю, так что все данные перед тем, как попасть в бд, у меня будут обработаны.

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

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