Pull to refresh

Comments 38

Все пробелы в коде убираются. Чем мне код отформатировать?
Отформатировать и подсветить попробуйте этим или этим.

По теме: давно заметил, что во многих классах абстрактакции БД есть такая полезная функция, как prepare. Например:
  1. $query = $db->prepare("SELECT * FROM table WHERE (id = ? AND user_id = ?)");
  2. $db->execute($query, array($_id, $_user_id));
Но зачастую она не фильтровала переменные, приходилось дописывать самому :)
Мда… Время идет, а люди не меняются. Последнюю строчку предыдущего поста можете не читать :)
Спасибо, отформатировал.
[pre]

и отключить автоформатирование текста
а почему бы не делать просто $username=htmlspecialchars($_GET['username']);?
Во-первых, htmlspecialchars() создан для совсем других целей и кавычки он не экранирует — можете проверить «kolpeex' or 1=1»==htmlspecialchars(«kolpeex' or 1=1»). У вас уже уязвимость :-)
Во-вторых, я написал в начале, что многие забывают о фильтрации.
В-третьих, из-за большого количества подобных строк код выглядит хуже. Слишком много в нем может быть $v = filter($v);. А тут две строки: запрос и его выполнение. Параметры прямо от пользователя.
Что для других целей это да. А вообще, htmlspecialchars и одиночные кавычки заменяет на сущности, если его запускать в таком виде htmlspecialchars($argument, ENT_QUOTES).
уважаемый, а потом вы собираетесь кавычки реплейсить обратно?
Не совсем понял вопроса, я просто напомнил человеку возможности функции. Зачем реплейсить обратно?

Лично для себя я htmlspecialchars использовал только при вставке данных, которые потом просто надо показать в браузере в виде, в котором их ввел пользователь (например какой то код).
А реплейсить их обратно потребуется, например, если Вы захотите отправить юзверю письмо в plain_text формате, или там сделать экспорт в CSV-формат, ну Вы поняли.

Приведенный пример очень плох, т.к. он смешивает данные с особенностями их представления в браузере. Как только Вам захочется получить данные в чистом виде, без html-сучностей, Вы имеете проблемы.
С тем что данные смешал согласен. Тогда просто помещать в базу экранированные/сериализованные данные, а в браузер через htmlspecialchars.
В базе должны лежать ЧИСТЫЕ данные. Экранировать при выводе в конкретный формат, в соответствии с его требованиями.
Был неправ. Запомню на будущее как надо. Спасибо!
Должны… Млять — никто тебе ничего не должен. Если ты кончаешь от своих ЧИСТЫХ данных в базе — это лично твое дело.

Да и вообще все зависит от поставленной задачи. Если нужно чтобы хранились тэги- храним тэги. Не надо — не храним.

А лишний раз стр/прег реплайсе юзать — помоему нафиг не нужно.

На счет примера аффтора — он бесспорно имеет право существовать
Да пожалуйста пожалуйста.
Умудри тебя Господь (с)
например вам пришел xml документ который вы хотите положить в бд или любая другая структура свойства которой вам нужно сохранить не изменив сути (те не заменив ', <> и тд на спец символы)
Тогда документ/данные экранировать или сериализовать. Вы мне это объясняете будто я пропагандирую повальное использование htmlspecialchars. Все надо использовать в зависимости от ситуации.
А еще можно не придумывать велосипед, а использовать существующие ORM, например doctrine или propel
Велосипед у них. У меня target-specified.
К тому же эти продукты для более широкого применения. Использовать их для фильтрации не есть труЪ :-)
Или подумать ещё и просто взять PDO. Эта статья предназначена для новичков, которые в 99% случаев имеют лишь несколько запросов во всей программе, и использовать ради этого пропел — есть битьё из пушки по воробьям. Со временем новичок сам к дойдёт до использования ORM, когда достигнет надлежащего уровня и соответственного размера и сложноcти приложений.
+ вам в карму за PDO (сам не использую, так что за дравую мысль)
Такой подход вроде как называют placeholder'ами, действительно действенно и удобно, и исключает саму возможность допустить SQL-инъекцию. Я лично в качестве варианта подстановки использую sprintf, где помимо всего прочего можно привести аргумент к конкретному типу. Кстати насчет готовых решений — такой подход вроде-бы присутствует в PDO.

Да и вообще, даже комментариях мануала по PHP советуют этот метод, в самом простом его варианте — mysql_query(sprintf($query, $arg1, $arg2)); — остается только один вопрос, почему этот подход упорно игнорируют разработчики популярных скриптов… не, ну на самом деле, какому-нибудь phpBB уже лет по десять, а как находили в нем SQL-инъекции так и находят по сей день.
в pdo есть все что нужно для фильтрации, смотрим ru.php.net/manual/en/pdo.prepare.php
а если задать свой PDOStatement то можно получить:
Copy Source | Copy HTML
  1.     public function bindValue($Parameter, $Value, $DataType = NULL)
  2.     {
  3.         if ($DataType === NULL)
  4.         {
  5.             $DataType = gettype($Value);
  6.         }
  7.         $DataType = strtolower($DataType);
  8.         if ($DataType === 'boolean' || $DataType === 'bool' || $DataType === PDO::PARAM_BOOL)
  9.         {
  10.             $DataType = PDO::PARAM_BOOL;
  11.         }
  12.         elseif ($DataType === 'null' || $DataType === PDO::PARAM_NULL)
  13.         {
  14.             $DataType = PDO::PARAM_NULL;
  15.         }
  16.         elseif ($DataType === 'integer' || $DataType === 'int' || $DataType === PDO::PARAM_INT)
  17.         {
  18.             $DataType = PDO::PARAM_INT;
  19.         }
  20.         elseif ($DataType === 'string' || $DataType === 'str' || $DataType === PDO::PARAM_STR)
  21.         {
  22.             $DataType = PDO::PARAM_STR;
  23.         }
  24.         elseif ($DataType === 'lob' || $DataType === PDO::PARAM_LOB)
  25.         {
  26.             $DataType = PDO::PARAM_LOB;
  27.         }
  28.         elseif ($DataType === 'stmt' || $DataType === PDO::PARAM_STMT)
  29.         {
  30.             $DataType = PDO::PARAM_STMT;
  31.         }
  32.         else
  33.         {
  34.             $DataType = PDO::PARAM_STR;
  35.         }
  36.  
  37.         return parent::bindValue($Parameter, $Value, $DataType);
  38.     }
  39.  
  40. $stmt->bindValue(":val1", 'string'); //string
  41. $stmt->bindValue(":val2", 123); //integer
  42. $stmt->bindValue(":val3", TRUE, 'int'); //integer


sprintf кстати тоже не плохой вариант, тока не кидает эксепшен в случае ошибок %)
Вряд-ли на хабре найдётся тот то напрямую подставляет значения массива GET в SQL-запрос, так как почти в любом мануале это твердят не один раз. А если и найдётся — то туда ему и дорога.
Рано или подно, но все, что предназначено для БД, попадает в SQL.
Использование дополнительной переменной от SQL-инъекций не избавляет :-)
Для этого отлично подходит Dbsimple, удобные плэйсхолдеры и условные выражения
Начальные примеры кода каие-то странные. Кто запрещает переменные с короткими названиями вставлять в код. Плейсхолдеры с валидацией по выбору пользователя реализованы очень приятно в goDB.
mysql_real_escape_string очень сильно увеличивает размер строки. Пример есть пример.
UFO just landed and posted this here
блокирование чуваков которые шлют не то что надо

Ни в коем случае этого делать нельзя. Я вот очень злюсь, когда меня при пен-тестинге блокируют, и низачто после этого (IP меняется довольно-таки просто) не стану писать отчет администратору. Плохой пример: video.xaknet.ru/

А не вставлять проверки хрен нает где… что бы потом охреневать с того что все фильтры разбросаны по хреновой тучи файлов.

Для этого и нужны параметризованные запросы — «спрятать» фильтрацию данных, чтобы глаза не мозолила.
Меня удивляет то кол-во народа, которые либо придумывают или используют чей то велосипед, или отсылают к Doctrine, Propel и тому подобным.
Один хабраюзер высказал здравую мысль о PDO, за что ему плюс в карму. Однако все поголовно забыли про mysqli и его prepared statments. Уж что-что, а эта библиотека давно в составе PHP и на ней работает phpMyAdmin. Стандартная mysql не поддерживает новые возможности MySQL версией 4.1 и выше. Один multi_query при правильном использовании чего стоит, а PDO в моём понимании лишняя абстракция, к тому же банальное использование LIMIT в запросах (кто-нить пишет запросы без LIMIT для постраничного вывода?) не будет работать нигде, кроме MySQL.
немного смущает то что данные передаются по ссылке см php.net/manual/en/mysqli-stmt.bind-param.php хотя наличие класса MySQLi_STMT дает возможность это исправить
судя по бенчмаркам blogs.vinuthomas.com/2006/08/07/benchmark-mysql-mysqli-pdo-in-php/ разницы особой нет (хотя на такое стыдно ссылаться, ни методики тестирования, ни кода)
про использование лимит давайте подробнее, мускул умеет LIMIT OFFSET если вы об этом
пример правильного на ваш взгляд multi_query тоже стоит привести
заранее спасибо
В моем проекте по веским причинам использовался SQLite, который, кажется, не предоставляет таких возможностей.
В Друпале например используется подстановка с помощью sprintf плюс некоторая дополнительная фильтрация.
Sign up to leave a comment.

Articles