Как переписать mysql_real_escape_string?

 
0
 
PHP
ava
animegirl | 19.03.2013, 19:46
Нужен рабочий вызов данной функции, без какого-либо соединения с базой, это возможно?
Comments (84)
ava
Fortop | 19.03.2013, 18:51 #
Предлагаю начать выносить предупреждения за вопросы в этом топике.

Цитата (animegirl @  19.3.2013,  18:46 findReferencedText)
Нужен рабочий вызов данной функции, без какого-либо соединения с базой, это возможно? 

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

added later:
http://dev.mysql.com/doc/refman/5.0/en/mys...ape-string.html

Первый же абзац начинающийся с Note после сигнатуры функции
ava
animegirl | 19.03.2013, 19:02 #
Fortop,
Charset известен, как его передать без соединения?
Либо как переписать функцию, то есть заменить своей, но с той же... надёжностью?
ava
Gold Dragon | 19.03.2013, 20:00 #
animegirl, а зачем тебе mysql_real_escape_string без базы?
ava
animegirl | 19.03.2013, 20:04 #
Gold Dragon, Чтоб экранировать данные.
ava
Gold Dragon | 19.03.2013, 20:05 #

PS
и ещё маленькая выписка из "официальных документов"
Цитата


This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQL extension should be used

т.е.
Цитата


Данное расширение устарело, начиная с версии PHP 5.5.0, и будет удалено в будущем. Используйте вместо него MySQLi или PDO_MySQL

ava
animegirl | 19.03.2013, 20:32 #
Gold Dragon,
С целью избежать SQL-Инъекции.
Какие функции имеют такую же надёжность?
ava
baldina | 19.03.2013, 21:03 #
Цитата (animegirl @  19.3.2013,  20:32 findReferencedText)
С целью избежать SQL-Инъекции.

инъекция может произойти только при запросе к бд. значит соединение есть (или будет).
рассказывайте всё, что то в ваших соображениях не так
ava
animegirl | 19.03.2013, 21:06 #
baldina,
Цитата (baldina @  19.3.2013,  21:03 findReferencedText)
значит соединение есть (или будет).

Будет... может быть, там дальше ещё хватает проверок, но часть данных надо "обезвредить" уже сейчас.
ava
Gold Dragon | 19.03.2013, 21:35 #
animegirl, а давай немного отойдём от того что ты хочешь.. Просто попробуй воспринять всё по другому.. Экранирование как MySQL уже ушло в прошлое  smile Просто используй подготовленные выражения и ничего экранировать не нужно и при этом всё очень безопасно.. Суть очень простая: запрос отдельно данные отдельно.. А плюсы: безопасно, быстрее и очень наглядно
ava
animegirl | 19.03.2013, 22:10 #
Цитата (Gold Dragon @  19.3.2013,  21:35 findReferencedText)
Экранирование как MySQL уже ушло в прошлое   Просто используй подготовленные выражения и ничего экранировать не нужно

Это как?!?!? А что нынче актуально?

Цитата (Gold Dragon @  19.3.2013,  21:35 findReferencedText)
а на Fortop не злись, он всегда чем-то не доволен

Ок, приму к сведению )
ava
Арантир | 19.03.2013, 22:29 #
Цитата (animegirl @  19.3.2013,  21:10 findReferencedText)
Это как?!?!? А что нынче актуально?

Это запрос и данные отправляются отдельно. Данные отправляются "как есть", но уже не являются частью запроса или чего-либо еще подобного, по-этому просто физически не могут нанести никакого вреда.
http://www.php.net/manual/ru/pdo.prepared-statements.php
http://www.php.net/manual/ru/mysqli.quicks...-statements.php
ava
animegirl | 19.03.2013, 22:34 #
Arantir,
Это мазахизм какой-то, пардон.
Мне не понятно, зачем усложнять простое, если раньше хватало одной команды, то теперь сделали несколько, в добавок классы эти. Спасибо, хоть основные команды продублировали процедурными обращениями.
ava
Fortop | 19.03.2013, 23:06 #
Цитата (animegirl @  19.3.2013,  19:02 findReferencedText)
Charset известен, как его передать без соединения?

никак


Цитата (animegirl @  19.3.2013,  19:02 findReferencedText)
Либо как переписать функцию, то есть заменить своей, но с той же... надёжностью? 

Исходники mysql открыты - так что вперед и с песней.



Цитата (animegirl @  19.3.2013,  22:34 findReferencedText)
Мне не понятно, зачем усложнять простое,

Вот и мне непонятно smile ты мазохистка?

Вот это зачем?
Цитата (animegirl @  19.3.2013,  21:06 findReferencedText)
Будет... может быть, там дальше ещё хватает проверок, но часть данных надо "обезвредить" уже сейчас.



Когда будет и если будет запись в БД - тогда и "обезвредите".
ava
Nett | 19.03.2013, 23:15 #
Используй http://www.php.net/manual/en/function.addslashes.php

addslashes($text);


Будет экранировать все кавычки и остальные нежелательные символы, например /.
ava
animegirl | 19.03.2013, 23:14 #
Цитата (Fortop @  19.3.2013,  23:06 findReferencedText)
Когда будет и если будет запись в БД - тогда и "обезвредите".

Есть таблица на ~30+ столбцов, для редактирования там записей есть скрипт, который проверяет данные к каждому из столбцов, и в зависимости от правильности и доступности использования, добавляет в вариаблу данные, в конце скрипта, вариабла с данными передаётся в запрос и отсылается.
Есть там примерно 30% столбцов, где неверные значения можно проигнорировать и просто не записывать их изменения, а вот остальные если неверны, тогда отказ и выдача ошибки. Вот вам и ситуация, данные надо обезопасить, но зачем делать лишние подключение, если есть не малый шанс, что оно в итоге не будет использовано?
ava
baldina | 19.03.2013, 23:15 #
Цитата (animegirl @  19.3.2013,  21:06 findReferencedText)
часть данных надо "обезвредить" уже сейчас

напомнило про монашку с морковкой....простите

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

Цитата (animegirl @  19.3.2013,  22:34 findReferencedText)
Это мазахизм какой-то, пардон.

нет, это другой уровень мышления при организации программ.
полезнее его понять, чем ругаться.
ваши типовые задачи при обращении к бд уже грамотно классифицировали, квалифицированно решили и облекли в ооп форму, предоставив отдельные и удобные средства для решения маленьких подзадач. можно заняться делом, не отвлекаясь на мелочи
ava
Gold Dragon | 19.03.2013, 23:19 #
animegirl, я тоже сначала пугался, а как осознал, так понял что проще некуда... и при этом запросы очень нагляднее..

Всё очень просто.. Вот если кратко

создаём новый объект mysqli

$mysqli_obj = new mysql('host', 'user_name', 'pass', 'db');

делаем подготовленное выражение

$qqq = $mysqli_obj->prepare("SELECT * FROM table WHERE name=? AND id=?");

загружаем данные

$qqq->bind_param("si", 'Вася', 33);

выполним запрос

$qqq->execute();


И получается что ты наглядно видишь запрос и он идёт отдельно и ты наглядно видишь переменные для запроса. И при этом определяешь их тип
ava
animegirl | 19.03.2013, 23:20 #
Цитата (baldina @  19.3.2013,  23:15 findReferencedText)
найдите точку, где сошлись запрос, выражение sql и данные пользователя. здесь и выполняйте escape

3 Раза перечитала, но всё равно не поняла, о чём вы.



Цитата (baldina @  19.3.2013,  23:15 findReferencedText)
нет, это другой уровень мышления при организации программ.полезнее его понять, чем ругаться.ваши типовые задачи при обращении к бд уже грамотно классифицировали, квалифицированно решили и облекли в ооп форму, предоставив отдельные и удобные средства для решения маленьких подзадач. можно заняться делом, не отвлекаясь на мелочи

Верю, но коней на переправе не меняют, у меня и так с сроками проблемы, а дополнительно вникать в новое мышление равносильно самоубийству.
ava
Gold Dragon | 19.03.2013, 23:23 #
animegirl, и самое главное.. ты учишься используя старую литературу.. Забудь ты уже про MySQL.. нет его больше, устарел  smile  MySQLi оставил процедурный подход и схожесть названий функций наверное только в память о былом..
ava
Fortop | 19.03.2013, 23:26 #
Цитата (animegirl @  19.3.2013,  23:14 findReferencedText)
Есть там примерно 30% столбцов, где неверные значения можно проигнорировать и просто не записывать их изменения, а вот остальные если неверны, тогда отказ и выдача ошибки. Вот вам и ситуация, данные надо обезопасить, но зачем делать лишние подключение, если есть не малый шанс, что оно в итоге не будет использовано? 

Валидация значений это одно.

а mysql_real_escape_string это другое.
Оно нужно только и только при вставке данных в базу.
Если данные неверны и не будут вставляться, то зачем их эскейпить?
ava
animegirl | 19.03.2013, 23:30 #
А вообще, мы ооооочень сильно отдалились от сути вопроса.
Мне нужна функция - костыль,. Если я правильно понимаю, то там чистый string replace, вопрос, в том, что на что менять.
ava
Fortop | 19.03.2013, 23:34 #
animegirl,


$data = array(1,2,3,4); // данные

if ($toQuery = mySuperFilter($data)) {
....
// где-то далеко в коде, а может и в другой функции вообще
// вставляем в запрос данные
    $query  = 'бла-бла-бла';
    foreach ($toQuery as &$v) {
        $v= mysql_real_escape_string($v) ;
    }
$query .= "'" . implode("','", $toQuery) . "'";

    mysql_query($query);

}


added later:
А насчет функции-костыля
Цитата (Fortop @  19.3.2013,  23:06 findReferencedText)
Исходники mysql открыты - так что вперед и с песней.

ava
animegirl | 19.03.2013, 23:37 #
Цитата (Fortop @  19.3.2013,  23:26 findReferencedText)
Валидация значений это одно.а mysql_real_escape_string это другое.Оно нужно только и только при вставке данных в базу.Если данные неверны и не будут вставляться, то зачем их эскейпить?

Надеюсь так будет более понятно:

$updates = array();
if(CHECK)
    {
    array_push($updates,"`table`.`column`=".mysql_real_escape_string($_POST['data']));
    }
//повторить 30 раз

if(!empty($updates))
    {
    waysql_query("UPDATE `table` SET ".implode(",",$updates)." WHERE ...");
    }
ava
Gold Dragon | 19.03.2013, 23:43 #
Цитата (animegirl @  20.3.2013,  00:30 findReferencedText)
Мне нужна функция - костыль


функция экранирует это:  \x00, \n, \r, \, ', " и \x1a

можешь воспользоваться например preg_replace() и "ручками" всё найти и экранировать  smile 
ava
animegirl | 19.03.2013, 23:46 #
Цитата (Fortop @  19.3.2013,  23:06 findReferencedText)
Исходники mysql открыты - так что вперед и с песней.

Хорошо, открыла архив, где искать хотя бы не подскажите?
ava
Fortop | 19.03.2013, 23:53 #
Цитата (animegirl @  19.3.2013,  23:37 findReferencedText)
if(CHECK)
  {
  array_push($updates,"`table`.`column`=".mysql_real_escape_string($_POST['data']));
  }

//повторить 30 раз

Ключевой вопрос. На этом этапе еще возможно решение "не писать в БД"?
Или уже будем писать в любом случае?

Если еще возможно, то я показал как нужно организовать работу.

Сначала проверяем все данные на нужные нам условия. И в конце, когда уже принято решение - будем писать в БД. 
  • Проверяем наличие данных в $updates
  • Подключаемся к БД
  • Производим экранирование данных для занесения в запрос.
  • формируем запрос
  • Выполняем его.
  • Профит


Цитата (animegirl @  19.3.2013,  23:46 findReferencedText)
Хорошо, открыла архив, где искать хотя бы не подскажите?

Э нет, не подскажу, воспользуйтесь поиском по содержимому файлов.
Функция там так и называется
ava
animegirl | 20.03.2013, 00:08 #
Цитата (Fortop @  19.3.2013,  23:53 findReferencedText)
Ключевой вопрос. На этом этапе еще возможно решение "не писать в БД"?Или уже будем писать в любом случае?

В том то и дело, что очень даже возможен, так как в тех самых вше упомянутых 70%, если CHECK  не пройден, то ничего никуда писаться не будет.
ava
Fortop | 20.03.2013, 01:55 #
Цитата (animegirl @  20.3.2013,  00:08 findReferencedText)
В том то и дело, что очень даже возможен, так как в тех самых вше упомянутых 70%, если CHECK  не пройден, то ничего никуда писаться не будет.

Тогда никакого
Цитата (animegirl @  19.3.2013,  23:37 findReferencedText)
"`table`.`column`=".mysql_real_escape_string($_POST['data'])

быть не должно

На этом этапе собираем данные, названия полей и что еще нужно.

Вызывать mysql_real_escape_string и формировать запрос будем тогда, когда это будет действительно нужно.
ava
animegirl | 20.03.2013, 04:11 #
Fortop,
Одного не понимаю, почему вам проще настоять на том, что спрашивающий человек, должен изменить логику действия своих скриптов, чем просто ответить на поставленный вопрос?

Не нашла в исходниках функцию эту, только её вызовы, без понятия почему  smile 
ava
Fortop | 20.03.2013, 05:26 #
Цитата (animegirl @  20.3.2013,  04:11 findReferencedText)
Одного не понимаю, почему вам проще настоять на том, что спрашивающий человек, должен изменить логику действия своих скриптов, чем просто ответить на поставленный вопрос?

Я ответил на поставленный вопрос smile и не на один.
Но их число у тебя не будет уменьшаться. Просто потому, что ты выбрала намного более сложный путь решения стоящей перед тобой задачи.

Поэтому намного проще будет, если сделаешь как тебе говорят smile И вопросов в дальнейшем будет меньше.

P.S. А у меня опыта немного больше, и работа у меня такая проверять программистов и подсказывать им. Поэтому я это все вижу и понимаю.
P.P.S. Никакую функцию в исходниках MySQL ты не искала
Потому что все есть в source/libmysql/libmysql.c на 1169й строчке

/*
  Add escape characters to a string (blob?) to make it suitable for a insert
  to should at least have place for length*2+1 chars
  Returns the length of the to string
*/

ulong STDCALL
mysql_escape_string(char *to,const char *from,ulong length)
{
  return (uint) escape_string_for_mysql(default_charset_info, to, 0, from, length);
}

ulong STDCALL
mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
             ulong length)
{
  if (mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
    return (uint) escape_quotes_for_mysql(mysql->charset, to, 0, from, length);
  return (uint) escape_string_for_mysql(mysql->charset, to, 0, from, length);
}

ava
animegirl | 20.03.2013, 05:34 #
Fortop,
Удивитесь, но честное слово - искала.
А те 2 функции, что там вызываются лежат в charset.c :P

Надо будет в них покопаться, Си это не совсем моя стихия.
ava
Fortop | 19.03.2013, 23:26 #
Цитата (animegirl @  19.3.2013,  23:14 findReferencedText)
Есть там примерно 30% столбцов, где неверные значения можно проигнорировать и просто не записывать их изменения, а вот остальные если неверны, тогда отказ и выдача ошибки. Вот вам и ситуация, данные надо обезопасить, но зачем делать лишние подключение, если есть не малый шанс, что оно в итоге не будет использовано? 

Валидация значений это одно.

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

added later:
Цитата (animegirl @  19.3.2013,  23:20 findReferencedText)
у меня и так с сроками проблемы, а дополнительно вникать в новое мышление равносильно самоубийству. 

Напомнило "чего тут думать? прыгать нужно".

Вобщем делай mysql_real_escape_string данным непосредственно перед вставкой в запрос.
И все. И сроки сэкономишь себе.
ava
animegirl | 19.03.2013, 23:30 #
А вообще, мы ооооочень сильно отдалились от сути вопроса.
Мне нужна функция - костыль,. Если я правильно понимаю, то там чистый string replace, вопрос, в том, что на что менять.
ava
Fortop | 19.03.2013, 23:34 #
animegirl,


$data = array(1,2,3,4); // данные

if ($toQuery = mySuperFilter($data)) {
....
// где-то далеко в коде, а может и в другой функции вообще
// вставляем в запрос данные
    $query  = 'бла-бла-бла';
    foreach ($toQuery as &$v) {
        $v= mysql_real_escape_string($v) ;
    }
$query .= "'" . implode("','", $toQuery) . "'";

    mysql_query($query);

}


added later:
А насчет функции-костыля
Цитата (Fortop @  19.3.2013,  23:06 findReferencedText)
Исходники mysql открыты - так что вперед и с песней.

ava
animegirl | 19.03.2013, 23:37 #
Цитата (Fortop @  19.3.2013,  23:26 findReferencedText)
Валидация значений это одно.а mysql_real_escape_string это другое.Оно нужно только и только при вставке данных в базу.Если данные неверны и не будут вставляться, то зачем их эскейпить?

Надеюсь так будет более понятно:

$updates = array();
if(CHECK)
    {
    array_push($updates,"`table`.`column`=".mysql_real_escape_string($_POST['data']));
    }
//повторить 30 раз

if(!empty($updates))
    {
    waysql_query("UPDATE `table` SET ".implode(",",$updates)." WHERE ...");
    }
ava
Gold Dragon | 19.03.2013, 23:43 #
Цитата (animegirl @  20.3.2013,  00:30 findReferencedText)
Мне нужна функция - костыль


функция экранирует это:  \x00, \n, \r, \, ', " и \x1a

можешь воспользоваться например preg_replace() и "ручками" всё найти и экранировать  :wink

added later:

...mysql_real_escape_string($_POST['data'])...
на будущее, нельзя так делать.. Fortop, правильно говорит про валидацию.. нельзя сразу из запроса данные использовать.. нужно всё таки приводить их в соответсвие
ava
animegirl | 19.03.2013, 23:46 #
Цитата (Fortop @  19.3.2013,  23:06 findReferencedText)
Исходники mysql открыты - так что вперед и с песней.

Хорошо, открыла архив, где искать хотя бы не подскажите?

added later:
Gold Dragon,
Как и во что экранирует?
Там ведь какой-то подвох, если нужен функции charset, значит не всё так просто.
Помню где-то промелькнуло, что была уязвимость, если экранировать не верно, то в итоге из одного спец символа, выходит другой, который так же допускает инъекцию.
ava
Fortop | 19.03.2013, 23:53 #
Цитата (animegirl @  19.3.2013,  23:37 findReferencedText)
if(CHECK)
  {
  array_push($updates,"`table`.`column`=".mysql_real_escape_string($_POST['data']));
  }

//повторить 30 раз

Ключевой вопрос. На этом этапе еще возможно решение "не писать в БД"?
Или уже будем писать в любом случае?

Если еще возможно, то я показал как нужно организовать работу.

Сначала проверяем все данные на нужные нам условия. И в конце, когда уже принято решение - будем писать в БД. 
  • Проверяем наличие данных в $updates
  • Подключаемся к БД
  • Производим экранирование данных для занесения в запрос.
  • формируем запрос
  • Выполняем его.
  • Профит


Цитата (animegirl @  19.3.2013,  23:46 findReferencedText)
Хорошо, открыла архив, где искать хотя бы не подскажите?

Э нет, не подскажу, воспользуйтесь поиском по содержимому файлов.
Функция там так и называется
ava
animegirl | 20.03.2013, 00:08 #
Цитата (Fortop @  19.3.2013,  23:53 findReferencedText)
Ключевой вопрос. На этом этапе еще возможно решение "не писать в БД"?Или уже будем писать в любом случае?

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


Цитата (Fortop @  19.3.2013,  23:53 findReferencedText)
Э нет, не подскажу, воспользуйтесь поиском по содержимому файлов.Функция там так и называется

Так и сделала уже, но там везде только вызовы этой функции, и нигде нету её конструктора.
ava
Fortop | 20.03.2013, 01:55 #
Цитата (animegirl @  20.3.2013,  00:08 findReferencedText)
В том то и дело, что очень даже возможен, так как в тех самых вше упомянутых 70%, если CHECK  не пройден, то ничего никуда писаться не будет.

Тогда никакого
Цитата (animegirl @  19.3.2013,  23:37 findReferencedText)
"`table`.`column`=".mysql_real_escape_string($_POST['data'])

быть не должно

На этом этапе собираем данные, названия полей и что еще нужно.

Вызывать mysql_real_escape_string и формировать запрос будем тогда, когда это будет действительно нужно.
ava
animegirl | 20.03.2013, 04:11 #
Fortop,
Одного не понимаю, почему вам проще настоять на том, что спрашивающий человек, должен изменить логику действия своих скриптов, чем просто ответить на поставленный вопрос?

Не нашла в исходниках функцию эту, только её вызовы, без понятия почему  smile 
ava
Fortop | 20.03.2013, 05:26 #
Цитата (animegirl @  20.3.2013,  04:11 findReferencedText)
Одного не понимаю, почему вам проще настоять на том, что спрашивающий человек, должен изменить логику действия своих скриптов, чем просто ответить на поставленный вопрос?

Я ответил на поставленный вопрос smile и не на один.
Но их число у тебя не будет уменьшаться. Просто потому, что ты выбрала намного более сложный путь решения стоящей перед тобой задачи.

Поэтому намного проще будет, если сделаешь как тебе говорят smile И вопросов в дальнейшем будет меньше.

P.S. А у меня опыта немного больше, и работа у меня такая проверять программистов и подсказывать им. Поэтому я это все вижу и понимаю.
P.P.S. Никакую функцию в исходниках MySQL ты не искала
Потому что все есть в source/libmysql/libmysql.c на 1169й строчке

/*
  Add escape characters to a string (blob?) to make it suitable for a insert
  to should at least have place for length*2+1 chars
  Returns the length of the to string
*/

ulong STDCALL
mysql_escape_string(char *to,const char *from,ulong length)
{
  return (uint) escape_string_for_mysql(default_charset_info, to, 0, from, length);
}

ulong STDCALL
mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
             ulong length)
{
  if (mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
    return (uint) escape_quotes_for_mysql(mysql->charset, to, 0, from, length);
  return (uint) escape_string_for_mysql(mysql->charset, to, 0, from, length);
}

ava
animegirl | 20.03.2013, 05:34 #
Fortop,
Удивитесь, но честное слово - искала.
А те 2 функции, что там вызываются лежат в charset.c :P

Надо будет в них покопаться, Си это не совсем моя стихия.
ava
krypt3r | 20.03.2013, 07:40 #
Защита от SQL-инъекции без подключения к БД — это нечто smile
ЗЫ. Веселый стал раздел  smile 
ava
Gold Dragon | 20.03.2013, 08:07 #
animegirl, хоть убей, не понимаю зачем тебе писать это 30 раз

array_push($updates,"`table`.`column`=".mysql_real_escape_string($_POST['data']));

когда можно просто поместить данные в массив если тебе так хочется

array_push($updates, $_POST['data']);

а потом в цикле сразу и использовать, что. то типа такого

foreach($updates as $value){
    //....
    $sql = "SELECT * FROM `table` WHERE `table`.`column` = '" . mysql_real_escape_string($value) . '"';
    // ...
}



И понятно что и где, да и код вместе с ресурсами сократишь в 30 раз

ava
Fortop | 20.03.2013, 11:53 #
Цитата (animegirl @  20.3.2013,  05:34 findReferencedText)
Надо будет в них покопаться

 smile 
точно мазохистка :)

ava
IgorIV | 20.03.2013, 20:28 #
Цитата (animegirl @  20.3.2013,  04:11 findReferencedText)
Одного не понимаю, почему вам проще настоять на том, что спрашивающий человек, должен изменить логику действия своих скриптов, чем просто ответить на поставленный вопрос?

Потому что логика действия скриптов продолжение логики мышления. По сути надо менять мышление. А там и скрипты подтянутся.
ava
IgorIV | 20.03.2013, 20:49 #
Цитата (animegirl @  19.3.2013,  23:14 findReferencedText)


Есть таблица на ~30+ столбцов, для редактирования там записей есть скрипт,  =это хорошо

который проверяет данные к каждому из столбцов, =это замечательно

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

в конце скрипта, вариабла с данными передаётся в запрос и отсылается.  =туда же

Есть там примерно 30% столбцов, где неверные значения можно проигнорировать и просто не записывать их изменения,  =понятно

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

Вот вам и ситуация, данные надо обезопасить, =зачем, если они правильны и доступны, в чём SQL-Инъекция 'girl' если до SQL дело не дойдёт

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

И насчёт MySQLi - http://www.php.net/manual/ru/mysqlinfo.api.choosing.php 
Шагайте в ногу
ava
IgorIV | 20.03.2013, 21:06 #
Покажи, пожалуйста, функцию waysql_query
ava
odminchek | 20.03.2013, 21:32 #
От лишнего подключения ИМХО ни база, ни что-либо другое нисколько не пострадает, это раз. Не использовать что-то там, где это необходимо использовать - ИМХО просто глупо, это два. Если писать свой велосипед, то вовсе не факт, что он будет работать так-же хорошо, как стандартная (специально для этих целей написанная) базовая функция, это три. Не хочу давать советов, но при реализации своих задач я лично прогоняю данные через mysqli_real_escape_string()  непосредственно перед выполнением запроса к базе, это четыре. Успехов.
ava
animegirl | 20.03.2013, 22:19 #
Цитата (Gold Dragon @ 20.3.2013,  08:07)
animegirl, хоть убей, не понимаю зачем тебе писать это 30 раз



array_push($updates,"`table`.`column`=".mysql_real_escape_string($_POST['data']));



когда можно просто поместить данные в массив если тебе так хочется



array_push($updates, $_POST['data']);



а потом в цикле сразу и использовать, что. то типа такого



foreach($updates as $value){
  //....
  $sql = "SELECT * FROM `table` WHERE `table`.`column` = '" . mysql_real_escape_string($value) . '"';
  // ...

}







И понятно что и где, да и код вместе с ресурсами сократишь в 30 раз



added later:

а  если не секрет, а что должно получится? Если  ты хочешь просто перечислить все условия, то это не самый быстрый и лучший вариант.. Для  подобного в MySQL есть  оператор IN

1. Все данные в один столбец?
2. Данные разные, проверки разные, там и числа и числа с плавающей точкой, и списки допустимых слов и много чего ещё.
3. Изменяются не все данные, а от 1 колонки и до всех колонок за раз, то есть, неизвестно, сколько придёт данных для замены.
4. Вы не обратили внимания, я перечисляю не условия, я перечисляю изменения, там стоит SET
ava
odminchek | 20.03.2013, 23:27 #
Мы не издеваемся. Мы совершенно искренне не понимаем, к чему всё это. На свете есть два типа людей. Одни задаются вопросом "Как?", другие - "Зачем?". И в большинстве случаев вторые правы.
ava
animegirl | 21.03.2013, 00:15 #
Цитата (doctor2k @ 20.3.2013,  23:27)
Мы не издеваемся. Мы совершенно искренне не понимаем, к чему всё это. На свете есть два типа людей. Одни задаются вопросом "Как?", другие - "Зачем?". И в большинстве случаев вторые правы.

Не спорю, быть может так, но это не то что надо, мне вот надо понять КАК... это:

/*
  Add escape characters to a string (blob?) to make it suitable for a insert
  to should at least have place for length*2+1 chars
  Returns the length of the to string
*/

ulong STDCALL
mysql_escape_string(char *to,const char *from,ulong length)
    {
    return (uint) escape_string_for_mysql(default_charset_info, to, 0, from, length);
    }

ulong STDCALL
mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, ulong length)
    {
    if (mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
        return (uint) escape_quotes_for_mysql(mysql->charset, to, 0, from, length);
        return (uint) escape_string_for_mysql(mysql->charset, to, 0, from, length);
    }


















/*
  Escape apostrophes by doubling them up

  SYNOPSIS
    escape_quotes_for_mysql()
    charset_info        Charset of the strings
    to                  Buffer for escaped string
    to_length           Length of destination buffer, or 0
    from                The string to escape
    length              The length of the string to escape

  DESCRIPTION
    This escapes the contents of a string by doubling up any apostrophes that
    it contains. This is used when the NO_BACKSLASH_ESCAPES SQL_MODE is in
    effect on the server.

  NOTE
    To be consistent with escape_string_for_mysql(), to_length may be 0 to
    mean "big enough"

  RETURN VALUES
    ~0          The escaped string did not fit in the to buffer
    >=0         The length of the escaped string
*/

size_t escape_quotes_for_mysql(CHARSET_INFO *charset_info, char *to, size_t to_length, const char *from, size_t length)
    {
    const char *to_start= to;
    const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
    my_bool overflow= FALSE;
    #ifdef USE_MB
        my_bool use_mb_flag= use_mb(charset_info);
    #endif
    for (end= from + length; from < end; from++)
        {
        #ifdef USE_MB
            int tmp_length;
            if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
                {
                if (to + tmp_length > to_end)
                    {
                    overflow= TRUE;
                    break;
                    }
                while (tmp_length--)
                    *to++= *from++;
                    from--;
                continue;
                }
    /*
      We don't have the same issue here with a non-multi-byte character being
      turned into a multi-byte character by the addition of an escaping
      character, because we are only escaping the ' character with itself.
     */
        #endif
        if (*from == '\'')
            {
            if (to + 2 > to_end)
                {
                overflow= TRUE;
                break;
                }
            *to++= '\'';
            *to++= '\'';
            }
        else
            {
            if (to + 1 > to_end)
                {
                overflow= TRUE;
                break;
                }
            *to++= *from;
            }
        }
    *to= 0;
    return overflow ? (ulong)~0 : (ulong) (to - to_start);
}








/*
  Escape string with backslashes (\)

  SYNOPSIS
    escape_string_for_mysql()
    charset_info        Charset of the strings
    to                  Buffer for escaped string
    to_length           Length of destination buffer, or 0
    from                The string to escape
    length              The length of the string to escape

  DESCRIPTION
    This escapes the contents of a string by adding backslashes before special
    characters, and turning others into specific escape sequences, such as
    turning newlines into \n and null bytes into \0.

  NOTE
    To maintain compatibility with the old C API, to_length may be 0 to mean
    "big enough"

  RETURN VALUES
    (size_t) -1 The escaped string did not fit in the to buffer
    #           The length of the escaped string
*/

size_t escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, size_t to_length, const char *from, size_t length)
    {
    const char *to_start= to;
    const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
    my_bool overflow= FALSE;
    #ifdef USE_MB
        my_bool use_mb_flag= use_mb(charset_info);
    #endif
    for (end= from + length; from < end; from++)
        {
        char escape= 0;
        #ifdef USE_MB
            int tmp_length;
            if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
                {
                if (to + tmp_length > to_end)
                    {
                    overflow= TRUE;
                    break;
                    }
                while (tmp_length--)
                    *to++= *from++;
                    from--;
                    continue;
                }
    /*
     If the next character appears to begin a multi-byte character, we
     escape that first byte of that apparent multi-byte character. (The
     character just looks like a multi-byte character -- if it were actually
     a multi-byte character, it would have been passed through in the test
     above.)

     Without this check, we can create a problem by converting an invalid
     multi-byte character into a valid one. For example, 0xbf27 is not
     a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \)
    */
            if (use_mb_flag && (tmp_length= my_mbcharlen(charset_info, *from)) > 1)
                escape= *from;
            else
        #endif
        switch (*from)
            {
            case 0:                /* Must be escaped for 'mysql' */
                escape= '0';
                break;
            case '\n':                /* Must be escaped for logs */
                escape= 'n';
                break;
            case '\r':
                escape= 'r';
                break;
            case '\\':
                escape= '\\';
                break;
            case '\'':
                escape= '\'';
                break;
            case '"':                /* Better safe than sorry */
                escape= '"';
                break;
            case '\032':            /* This gives problems on Win32 */
                escape= 'Z';
                break;
            }
        if (escape)
            {
            if (to + 2 > to_end)
                {
                overflow= TRUE;
                break;
                }
            *to++= '\\';
            *to++= escape;
            }
        else
            {
            if (to + 1 > to_end)
                {
                overflow= TRUE;
                break;
                }
            *to++= *from;
            }
        }
    *to= 0;
    return overflow ? (size_t) -1 : (size_t) (to - to_start);
}








переписать на ПХП без потери безопасности.
Я частично понимаю ход действий, но не до конца понимаю, что именно и зачем там делается, я С++ занималась в далёком 2006ом и продлилось это очень и очень не долго. Мне не хватает моих знаний, а вы вместо того, чтоб просто протянуть руку подвернувшему ногу и упавшему человеку, столпились вокруг, хохочите, и снимаете на мобильники. Именно так и только так, я это вижу на данный момент,
ava
IgorIV | 21.03.2013, 00:22 #
Цитата (animegirl @  21.3.2013,  00:15 findReferencedText)
а вы вместо того, чтоб просто протянуть руку подвернувшему ногу и упавшему человеку, столпились вокруг, хохочите, и снимаете на мобильники

Мне стало стыдно, я развернулся и ушёл.
ava
baldina | 21.03.2013, 00:55 #
Цитата (animegirl @  21.3.2013,  00:15 findReferencedText)
Мне не хватает моих знаний

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

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

вот вы пишете
Цитата (animegirl @  21.3.2013,  00:15 findReferencedText)
переписать на ПХП без потери безопасности

однако в том месте, где вы это применяете, еще угрозы безопасности просто нет.
оставьте вашу строчку, полученную от пользователя, как есть, без escape, и переходите в то место кода, где эта строчка соединяется с sql запросом. если она тут и соединяется (ужас), не соединяйте, а передайте строки дальше по отдельности. и перед вызовом mysql_query соедините строки, предварительно вызвав mysql_real_escape_string. в этом месте уже есть соединение с базой.
разве это сложно?
ava
baldina | 21.03.2013, 01:10 #
я переиначил фрагмент вашего кода (это то о чем говорил Gold Dragon),

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

$updates = array();
if(CHECK)
    {
    //array_push($updates,"`table`.`column`=".mysql_real_escape_string($_POST['data']));
    array_push($updates,$_POST['data']);
    }
//повторить 30 раз
if(!empty($updates))
    {
       function escape_and_set ($str) {
          return "`table`.`column`=".mysql_real_escape_string($str);
       }
       $updates = array_map  ('escape_and_set', $updates);
    
    mysql_query("UPDATE `table` SET ".implode(",",$updates)." WHERE ...");
    }
ava
ksnk | 21.03.2013, 06:11 #
Каждая задача имеет простое, понятное решение  smile 
animegirl
Цитата (animegirl @  19.3.2013,  18:46 findReferencedText)
Нужен рабочий вызов данной функции, без какого-либо соединения с базой, это возможно? 


mysql_escape_string ?
ava
animegirl | 21.03.2013, 08:49 #
ksnk,
Истина всё время была где-то рядом )
Спасибо.
ava
baldina | 21.03.2013, 09:27 #
ksnk, зачем?  smile 
ava
ksnk | 21.03.2013, 10:05 #
baldina, У человека 100 файлов с функциями, из которых сочиняется сайт. Без классов. И это сознательное решение. С глобалами. И это тоже сознательное решение. Что еще вы от него хотите? Научить программированию?

P.S. Кстати, Arantir уже намекал автору на эту функцию.  Правда очень тонко...
ava
Fortop | 21.03.2013, 13:05 #
ksnk, нужно только помнить что mysql_escape_string  фактически не защищает ничего.

Особенно при прямой инъекции $_POST в запросы как у автора темы.
ava
ksnk | 21.03.2013, 13:30 #
Цитата (Fortop @  21.3.2013,  13:05 findReferencedText)
Особенно при прямой инъекции $_POST в запросы как у автора темы.

Это как это? Можно поточнее?
Вся разница между этими функциями, imho, - в использовании кодовой таблицы установленной юзером или по умолчанию.  Все символы используемые для иньекций, вроде, экранируются.
ava
baldina | 21.03.2013, 13:58 #
безопасно. независимо от кодировки первые 127 (сюда попадают кавычки и т.п.) всегда одинаковы
Цитата


string mysql_escape_string ( string $unescaped_string )

Функция экранирует unescaped_string таким образом, после чего её можно безопасно использовать в mysql_query(). 



еще addslashes() имеется, а также quotemeta()
ava
Fortop | 21.03.2013, 14:03 #
Цитата (ksnk @  21.3.2013,  13:30 findReferencedText)
Это как это? Можно поточнее? 



http://security.stackexchange.com/question...-tables-using-l
ava
baldina | 21.03.2013, 14:03 #
http://dev.mysql.com:
Цитата


mysql_real_escape_string()

...

Strictly speaking, MySQL requires only that backslash and the quote character used to quote the string in the query be escaped. This function quotes the other characters to make them easier to read in log files.

кодировка требуется для other characters
ava
baldina | 21.03.2013, 14:21 #
Цитата (Fortop @  21.3.2013,  14:03 findReferencedText)


http://security.stackexchange.com/question...-tables-using-l 


написано красиво, но что-то не могу сообразить, как это можно практически использовать.
приведите пример строки в двубайтной кодировке, которая, будучи обработана mysql_escape_string(), т.е. как однобайтная, позволит выполнить запрос злоумышленника.
допускаю, что на экзотических кодировках (каких?) такое возможно, только насколько это близко к нашей реальности (точнее, реальности
animegirl  smile )
ava
Fortop | 21.03.2013, 14:24 #
Цитата (baldina @  21.3.2013,  14:21 findReferencedText)
приведите пример строки в двубайтной кодировке

Увы не приведу.

Поскольку детально взломами не занимался.
ava
baldina | 21.03.2013, 14:48 #
мне кажется автор того ответа тоже затруднился бы: вот экранировать однобайтную как двубайтную - другое дело.
а в однобайтной, где бы кавычка ни стояла, она будет экранирована.
если только в результате экранирования один символ не превращается в другой, но в юникоде это не так, а других кодировок вроде китайского письма мне неведомо.
ava
ksnk | 21.03.2013, 15:50 #
Fortop,
Что-то я не убежден. В кирилической utf-8 кодировке корректные символы в обоих байтах > #80 и никак не похожи на кавычки. Вероятно есть более другие кодовые таблицы, но мне они не знакомы.

Нашел вот такое на php.net
Цитата


Замечание:



mysql_escape_string() не экранирует символы % и _.


Это - способ навредить запросу, использующему like. Правда на иньекцию, imho, тоже не тянет.
ava
animegirl | 21.03.2013, 19:41 #
Не об этом ли речь господа?
http://stackoverflow.com/questions/5741187...l-escape-string
ava
Gold Dragon | 21.03.2013, 20:11 #
Цитата


1. Все данные в один столбец?

2. Данные разные, проверки разные, там и числа и числа с плавающей точкой, и списки допустимых слов и много чего ещё.

3. Изменяются не все данные, а от 1 колонки и до всех колонок за раз, то есть, неизвестно, сколько придёт данных для замены.

4. Вы не обратили внимания, я перечисляю не условия, я перечисляю изменения, там стоит SET


animegirl, по моему ты уже перемудрила со всем чем можно... Какие данные, какие проверки??? Как ты вообще проверяешь данные если ты их просто экранировать хочешь? Я всё загнал в массив.. а уж как применять массив - дело третье.. Нужен тебе SET, ну так и делай SET, не нравится циклы, ну так преобразуй массив в строку..

И вообще, я (и не только я) просто ЖАЖДУ узнать всю задачу которую надо решить именно таким извратом..  smile НУ никак я не могу понять как после экранирования можно определить подходят данные для запроса или нет..

И если ты не знаешь что приходит и в каком количестве, и при этом из всех проверок только какое-то мнимое экранирование, то, моё мнение, это очень неправильно спроектированная задача.
ava
odminchek | 21.03.2013, 20:33 #
Цитата (Gold Dragon @  21.3.2013,  20:11 findReferencedText)
animegirl, по моему ты уже перемудрила со всем чем можно... Какие данные, какие проверки??? Как ты вообще проверяешь данные если ты их просто экранировать хочешь? Я всё загнал в массив.. а уж как применять массив - дело третье.. Нужен тебе SET, ну так и делай SET, не нравится циклы, ну так преобразуй массив в строку..


  И вообще, я (и не только я) просто ЖАЖДУ узнать всю задачу которую надо решить именно таким извратом..   НУ никак я не могу понять как после экранирования можно определить подходят данные для запроса или нет..



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

+1
ava
baldina | 21.03.2013, 20:44 #
Цитата (animegirl @  21.3.2013,  19:41 findReferencedText)
Не об этом ли речь господа?

http://stackoverflow.com/questions/5741187...l-escape-string 

 smile конец китайцам...

Цитата (Gold Dragon @  21.3.2013,  20:11 findReferencedText)
animegirl, по моему ты уже перемудрила со всем чем можно... Какие данные, какие проверки?

да не она перемудрила, это ей в наследство досталось
animegirl, но код таки надо переписать, когда аврал пройдет
ava
Fortop | 22.03.2013, 02:00 #
Цитата (baldina @  21.3.2013,  20:44 findReferencedText)
да не она перемудрила, это ей в наследство досталось

Слушай, ну отрефакторить 7мб кода на предмет правильной работы с БД можно в течении суток.

Это крайне упростит последующую работу.
ava
animegirl | 22.03.2013, 02:07 #
Ну могу сказать одно, по поводу выбора движка вы победили, будет лишний часок, сменюсь на mysqli так как всё равно всё вызовы в одном файле )
ava
Gold Dragon | 22.03.2013, 06:22 #
animegirl, да мы обсуждали дольше.. у же давно бы сменилась  :wink

но ты так и не сказала что это за такой грандиозный проект ..
ava
baldina | 22.03.2013, 10:57 #
Цитата (Fortop @  22.3.2013,  02:00 findReferencedText)
отрефакторить 7мб кода на предмет правильной работы с БД можно в течении суток

это когда хорошо понимаешь
ava
animegirl | 22.03.2013, 19:31 #
Цитата (Gold Dragon @  22.3.2013,  06:22 findReferencedText)
animegirl, да мы обсуждали дольше.. у же давно бы сменилась

Ну так смена движка, это передела 10 функций в одном файле, что не затронет ничего другого, сделаю вообще два варианта, одной вариаблой можно будет переключать ;)


Цитата (Gold Dragon @  22.3.2013,  06:22 findReferencedText)
но ты так и не сказала что это за такой грандиозный проект ..

Слишком строгий договор, и так слишком много выкладываю.
ava
Fortop | 22.03.2013, 22:36 #
Цитата (animegirl @  22.3.2013,  02:07 findReferencedText)
 сменюсь на mysqli 

заодно перейди на prepared statements
ava
animegirl | 23.03.2013, 03:57 #
Цитата (Fortop @  22.3.2013,  22:36 findReferencedText)
заодно перейди на prepared statements

Это не получится сделать так же легко и просто, да и не нравится мне этот метод, они вообще без классовой ерунды работают?
ava
baldina | 23.03.2013, 18:29 #
Цитата (animegirl @  23.3.2013,  03:57 findReferencedText)
они вообще без классовой ерунды работают?

да.

mysqli_stmt mysqli_prepare ( mysqli $link , string $query );

но классы не ерунда, думаю в следующих темах ме сможем убедить вас)
ava
animegirl | 25.03.2013, 07:34 #
Не совсем понимаю, а этой функции нужен коннект или она самостоятельна?
http://www.php.net/manual/en/mysqli.real-escape-string.php
ava
Fortop | 25.03.2013, 10:23 #
string mysqli_real_escape_string ( mysqli $link , string $escapestr )
ava
baldina | 25.03.2013, 10:52 #
нужен

string mysqli_real_escape_string ( mysqli $link , string $escapestr )
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
advanced
Submit