Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Интернет » Web-программирование » DEL

Модерирует : Cheery

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10

Открыть новую тему     Написать ответ в эту тему

israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
То есть, если я правильно тебя понимаю, твой ответ - проверять при помощи mysql_real_escape_string() и htmlspecialchars() и всё? И не париться?

Всего записей: 925 | Зарегистр. 28-07-2007 | Отправлено: 23:31 11-10-2009 | Исправлено: israel_rider, 23:31 11-10-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
israel_rider

Цитата:
твой ответ - проверять при помощи mysql_real_escape_string() и htmlspecialchars() и всё? И не париться?

если правильно использовать, то да

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 23:44 11-10-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Cheery, помогите пожалуйста. Напишите, что Вы имеете в виду, говоря - "если правильно использовать"? Применительно к моему, конкретно описываемому мною случаю, когда приходится проверять данные, не зная заранее, где они после будут использоваться - в SQL запросе, или выводиться прямо на веб-стренице.
А ещё лучше, дайте пример кода. Ведь код, то который здесь требуется, всего пару строк.

Всего записей: 925 | Зарегистр. 28-07-2007 | Отправлено: 23:50 11-10-2009 | Исправлено: israel_rider, 23:51 11-10-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
israel_rider

Цитата:
говоря - "если правильно использовать"

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

Цитата:
Применительно к моему, конкретно описываемому мною случаю, когда приходится проверять данные, не зная заранее, где они после будут использоваться - в SQL запросе, или выводиться прямо на веб-стренице.

и? применяйте и экранирование и преобразование htmlentities

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 00:15 12-10-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

Цитата:
применяйте и экранирование и преобразование htmlentities

Спасибо, понял. Значит, получается так -  
 

Код:
 
function tep()  
    {  
        foreach($_REQUEST as $key => $val){  
            $preliminary = mysql_real_escape_string($val);
            $this->AllRequest[$key] = htmlspecialchars($preliminary);  
        }  
    }  
 


Всего записей: 925 | Зарегистр. 28-07-2007 | Отправлено: 00:47 12-10-2009
andead



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
israel_rider
да, ну и желательно приводить типы

Всего записей: 1821 | Зарегистр. 22-09-2005 | Отправлено: 00:49 12-10-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Принудительно приводить типы? А к чему их приводить? Делать все передаваемые данные "string"? Так а у меня же там ещё и "integer" передаюся.... И поди, знай, может даже где нибудь ещё  и "float" затешется....
Поясните пожалуйста, я не понимаю....

Всего записей: 925 | Зарегистр. 28-07-2007 | Отправлено: 00:56 12-10-2009 | Исправлено: israel_rider, 09:21 12-10-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Я очень сожалею, что ни кто из знающих профессионалов так и не ответил на мой последний вопрос. Неужели его сочли настолько глупым и нелепым? А у меня уже возникла следующая проблема, и как раз с типами.  
Дело в том, что, как я уже написал, работа сайта требует самые разные типы в «$_REQUEST». Так вот, и функция mysql_real_escape_string() и htmlspecialchars() на входе требуют «string». И когда через «$_REQUEST» потребовалось передать массив, сайт сработал неправильно. Пришлось переписать конструктор. И теперь он выглядит так:

Код:
 
var $AllRequest;
 
    function __construct()  
    {  
         
        $MySqlHostname = "localhost";
        $MySqlUsername = "имя";
        $MySqlPassword = "пароль";
        $MySqlDatabase = "база данных";
        $dblink = mysql_connect($MySqlHostname, $MySqlUsername, $MySqlPassword) or die("Error :: Unable to connect to database");      
        mysql_select_db($MySqlDatabase) or die( "Error :: Unable to select database");  
        mysql_query("SET NAMES UTF8");
         
        foreach($_REQUEST as $key => $val){
            if (is_array($val)) $this->AllRequest =    $_REQUEST;  
            else {
                $preliminary = mysql_real_escape_string($val);
                $this->AllRequest[$key] = htmlspecialchars($preliminary);  
            }
        }  
     }    
 

Сайт работает, но, как можно видеть, сейчас, если через «$_REQUEST» передаётся массив, то он не проверяется. Я не просматривал весь код сайта, но думаю, там наверняка найдутся места, где элементы этого массива будут и подставляться в запросы, и выводиться на страницах сайта. Следовательно вопрос – если в «$_REQUEST» будет содержаться массив, как его проверять? Точно так же, как я проверяю сам «$_REQUEST»? Делать итерацию по нему при помощи фунции foreach()? Или есть какое то более оригинальное решение в моём варианте?  

Всего записей: 925 | Зарегистр. 28-07-2007 | Отправлено: 16:32 12-10-2009 | Исправлено: israel_rider, 16:37 12-10-2009
andead



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
А к чему их приводить

к тем что используются в mysql
 

Цитата:
Так а у меня же там ещё и "integer" передаюся.... И поди, знай, может даже где нибудь ещё  и "float" затешется....

а кто сказал что будет легко?)
 

Цитата:
так и не ответил на мой последний вопрос

вам два человека одно и тоже написали
 

Цитата:
Следовательно вопрос – если в «$_REQUEST» будет содержаться массив, как его проверять?

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

Всего записей: 1821 | Зарегистр. 22-09-2005 | Отправлено: 17:04 12-10-2009 | Исправлено: andead, 17:09 12-10-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

Цитата:
вынесите функцию обработки переменной в отдельную функцию и обрабатывайте хоть строки, хоть массивы через рекурсию

Класс. Всё понял. Спасибо. Прямо сейчас и займусь.

Всего записей: 925 | Зарегистр. 28-07-2007 | Отправлено: 17:07 12-10-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Как всё просто показалось вначале.... В результате, только через сутки долбления головой о стену узнал о существовании функции array_walk_recursive(), которая позволила реализовать поданную andead - ом идею....
 
Добавлено:
Вот что получилось в результате:

Код:
 
function __construct()  
    {  
        $AllRequest = $_REQUEST;
        array_walk_recursive($AllRequest, array($this, 'security_check'));
         
        $this->AllRequest = $AllRequest;
    }
         
         
     function security_check(&$item, $key)
    {
            if (!is_numeric($item)) {
                  $MySqlHostname = "localhost";
                  $MySqlUsername = "имя";
                  $MySqlPassword = "пароль";
                  $MySqlDatabase = "база";
                  $dblink = mysql_connect($MySqlHostname, $MySqlUsername, $MySqlPassword) or die("Error :: Unable to connect to database");    
                   mysql_select_db($MySqlDatabase) or die( "Error :: Unable to select database");  
                   mysql_query("SET NAMES UTF8");
        
                   $item = htmlspecialchars($item, ENT_QUOTES);  
                   $item = mysql_real_escape_string($item);  
            }  
      }    
 

Хотелось бы выслушать советы, насколько грамотно всё получилось. По поводу типов. Правильно ли, допустим, что если условие "is_numeric($item) выполняется, то значение проверять вообще не нужно?
Пока тестирую. Вроде пока работает....

Всего записей: 925 | Зарегистр. 28-07-2007 | Отправлено: 16:14 13-10-2009 | Исправлено: israel_rider, 00:23 14-10-2009
evle



1 + int rand(100);
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
israel_rider
1. Отдельное подключение к базе и запрос для каждого поля в REQUEST — это, конечно, гениально, но, боюсь, хостер не оценит.
2. Лучше всё-таки понять, что же делают функции htmlspecialchars и mysql_real_escape_string, и зачем они это делают, чтобы не было соблазна мешать их в кучу.
3. На мой вкус обрабатывать весь REQUEST таким образом несколько избыточно. Если, конечно, он целиком потом не пойдёт в запрос.

----------
For every complex problem, there is a solution that is simple, neat, and wrong.

Всего записей: 2110 | Зарегистр. 03-02-2005 | Отправлено: 20:49 16-10-2009 | Исправлено: evle, 21:01 16-10-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
evle

Цитата:
Отдельное подключение к базе и запрос для каждого поля в REQUEST — это, конечно, гениально, но, боюсь, хостер не оценит.

http://us2.php.net/mysql_connect

Цитата:
If a second call is made to mysql_connect()  with the same arguments, no new link will be established, but instead, the link identifier of the already opened link will be returned. The new_link  parameter modifies this behavior and makes mysql_connect() always open a new link, even if mysql_connect() was called before with the same parameters. In SQL safe mode, this parameter is ignored.  

 
но насчет выбора базы и тд - да.. лишнее..  
 
 
israel_rider
я делаю так

Код:
function db_connect()
{
    static $connected = 0;
 
    if (!$connected) {
        $link = @mysql_connect(DB_HOST, DB_UID, DB_PWD);
        if ($link) {
            mysql_select_db(DB_DB);
            $connected = 1;
        } else {
            exit("Unable to connect to database.  Please try again later.\n");
        }
    }
}

и вызываю из каждой функции работающей с базой.

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 21:52 16-10-2009 | Исправлено: Cheery, 21:53 16-10-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
evle, рад твоим критическим замечаниям. Попробую всё же объяснить свою позицию, что бы в результате диалога я смог выбрать наиболее правильное решение.
Дело в том, что как я уже писал выше, когда начал обсуждать данную проблему, я обнаружил, что 80 процентов данных из REQUEST идут затем в запросы базы данных не проверяясь. И, в то же время, эти данные идут через базовый класс. Поэтому я и принял решение поставить функцию проверки в этой единственной точке, через которую они проходят. Вместо того, чтобы лазить по всему сайту (немаленькому) выискивать, и переделывать все запросы. У меня тоже были сомнения, не перегружу ли я хостинг. И я их высказывал несколькими постами выше. Если ты мог видеть. И если ты мог видеть, я получил ответ, что вроде бы и ни чего страшного. Что и практика подтвердила тоже. Ни я, ни мой клиент – хозяин сайта, после установки моей функции не почувствовали, что сайт стал работать медленнее.  
Далее. Я знаю,
Цитата:
что же делают функции htmlspecialchars и mysql_real_escape_string, и зачем они это делают
но, как я уже писал несколькими постами выше, данные из REQUEST идут и в запросы к базе данных, и выводятся на сайте и их видит пользователь. Поэтому я и решил проверять REQUEST обоими функциями в одном месте, вместо того, что бы лазить по всему сайту, и вставлять каждую из этих функций именно в то место, где нужна именно она. И об этом я консультировался постами выше, и в принципе, получил ответ, что да, сделать так можно. Все это можно видеть несколькими постами выше.  
Позже, идея проверять REQUEST обоими функциями подряд дала мне ошибку, и я от этой идеи отказался. Об этом я подробно написал здесь - http://forum.ru-board.com/topic.cgi?forum=31&topic=15632 .
Короче, всё, что сказал ты и я, можно подытожить короткой фразой – Да, обрабатывая весь REQUEST в одном месте я увеличиваю нагрузку на сервер, но альтернатива этому получается только одна – по сути, переделывать весь сайт.
Я буду счастлив продолжить диалог, что бы всё понять, и принять наиболее правильное решение. Прошу прощения, если что то до меня доходит не сразу.
 
 
Добавлено:
Cheery, поясните пожалуйта, я правильно понял идею Вашей функции? Смысл её в строке -  static $connected = 0;  
То есть идея в том, что, если подключение к базе данных уже существует, функция просто не сработает? Поскольку $connected уже будет равно единице? То есть, не будет ненужных, паралельных подключений, перегружающих сервер?

Всего записей: 925 | Зарегистр. 28-07-2007 | Отправлено: 21:55 16-10-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
israel_rider
честное слово - вы порой утомляете. вы что то нового кроме static увидели? ну зачем переспрашивать очевидное.
данный способ не сработает только в одном случае - если база вылетит на момент работы скрипта (то есть зависит от его длительности). соединение установится, но что то потом может не сработать.
а так - не важно какую функцию работы с базой вызовите - сначала установится соединение и больше не будет дергать базу. Кроме случая когда вызывается mysql_close в лоб - тогда этот метод тоже выдаст ошибку

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 22:51 16-10-2009 | Исправлено: Cheery, 22:52 16-10-2009
evle



1 + int rand(100);
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Cheery
Хм. Согласен; не знал, что php это кеширует. Видимо, как раз для таких случаев. :-)
israel_rider

Цитата:
я получил ответ, что вроде бы и ни чего страшного

Что-то я не вижу, чтобы кто-то утверждал, что  

Код:
 
                   mysql_select_db($MySqlDatabase) or die( "Error :: Unable to select database");  
                   mysql_query("SET NAMES UTF8");  
 

в цикле — это ничего страшного.  

Цитата:
Поэтому я и решил проверять REQUEST обоими функциями в одном месте

Видимо, всё-таки не понимаешь.

Цитата:
получил ответ, что да, сделать так можно

Сделать можно много чего. Вопрос в том, к чему это приведёт. Например, htmlspecialchars перед вставкой в базу приведёт к тому, что в базе окажутся не сами данные, а их html-представление. Отсюда появятся проблемы с поиском, сортировкой, выдачей в не-html виде. Если не делать htmlspecialchars или его аналог вообще, можно получить сломаный html, а если данные пришли от пользователя, то ещё и опасный. Никто же не помешает ввести вместо какого-нибудь поля '<script src=...>'.

----------
For every complex problem, there is a solution that is simple, neat, and wrong.

Всего записей: 2110 | Зарегистр. 03-02-2005 | Отправлено: 15:27 17-10-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
evle , на счёт замещания, что нельзя помещать подсоединение к базе даннвх в цикл, спасибо. Теперь понял, сейчас переделаю. Один из вариантов - поместить туда функцию от Cheery. Тогда, если соединение с базой уже установлено, второй раз оно вызываться уже не будет.
 
 
Добавлено:
На счёт второй части твоего замечания тоже огромное спасибо! Тоже всё понял в конце концов. Буду делать выводы.
В результате всего разговора я понял, что мне не удасться проверять данные поступающие из REQUEST в одном месте. Мне придётся в каждом конкретном случае применять или htmlspecialchars или mysql_real_escape_string, в зависимости от того, как используются конкретные данные.

Всего записей: 925 | Зарегистр. 28-07-2007 | Отправлено: 17:05 17-10-2009
evle



1 + int rand(100);
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Боюсь, ты так и не понял. Ни htmlspecialchars, ни mysql_real_escape_string не предназначены для «проверки» входных данных. mysql_real_escape_string оформляет строку для использования в запросе. htmlspecialchars готовит выходные данные для вставки в html. В обоих случаях данные уже считаются корректными, вопрос лишь в правильном их «отображении». Соответственно, применяемая функция должна соответствовать синтаксису выходного формата.
 
Так вот, ни то, что поступает в базу, ни то, что выдаётся на страницу, не связано напрямую с REQUEST. Туда должны попадать уже проверенные и отфильтрованные данные. Проверку можно делать чем-нибудь таким, простым strip_tags, приведением к int для чисел, и т. п. Проверка зависит от ожидаемых данных; если в поле ожидалось число, а оказалась дата, твоя функция никак это не обработает. Максимум, не допустит ошибки в синтаксисе SQL и инъекции. При вставке таких данных произойдёт преобразование типов, и в базе окажется чёрт те что, хотя обычно и довольно безобидное.
 
Надеюсь, не зря писал.

----------
For every complex problem, there is a solution that is simple, neat, and wrong.

Всего записей: 2110 | Зарегистр. 03-02-2005 | Отправлено: 21:27 17-10-2009 | Исправлено: evle, 21:28 17-10-2009
israel_rider

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Нет не зря. Сейчас буду пробовать переделывать...

Всего записей: 925 | Зарегистр. 28-07-2007 | Отправлено: 21:30 17-10-2009
evle



1 + int rand(100);
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Да, и по поводу соединения с базой. На мой вкус, логичнее делать это один раз и сильно заранее. Где-нибудь в конструкторе того, что будет записывать данные.

----------
For every complex problem, there is a solution that is simple, neat, and wrong.

Всего записей: 2110 | Зарегистр. 03-02-2005 | Отправлено: 21:31 17-10-2009
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9 10

Компьютерный форум Ru.Board » Интернет » Web-программирование » DEL


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru