1. PHP / Говнокод #17071

    +163

    1. 1
    $result = $db->query("update `" . $table_prefix . "options` set `option_value`='a:2:{i:0;b:0;s:8:" . '"auto_add"' . ";a:0:{}}' where `option_name`='nav_menu_options';");

    unserialize "глазами на лету" - ЛЕГКО!!!!

    Запостил: taras_shs, 06 Ноября 2014

    Комментарии (16) RSS

    • Господи, даже при наличии PDO все равно строки вручную конкантенируют. Там небось и SQL Injection где-то притаилась.
      Ответить
      • Говорят: "Сколько волка не корми - он всё равно в лес смотрит".
        Ответить
      • потому что PDO - это сложное API. вот почему нельзя было бы запилить параметризированные запросы тем же синтаксисом, что и интерполяцию строк?
        Ответить
      • Я никогда не думал, что так сложно заставить разработчиков использовать prepared statements, пока сам не попробовал. Они будут экранировать, экранировать экранированное, но склеивать запросы руками не перестанут.
        Ответить
        • > Я никогда не думал, что так сложно заставить разработчиков использовать prepared statements, пока сам не попробовал.
          Пока сам не попробовал использовать prepared statements?

          > но склеивать запросы руками не перестанут
          К сожалению, не всё можно забиндить.
          Ответить
          • > Не всё можно забиндить

            Cодержимое IN (...), например.
            Я в таком случае генерю IN (?, ?, ?, ?) и биндю аргументы.
            Ответить
            • Кстати, а ведь можно сделать свой препроцессинг, и добавить какой-нибудь ??, который будет требовать массив в соответствующем слоте параметров, и раскрываться в (?, ?, ?, ?) и пачку параметров...

              Как-то так:
              $cursor = $db->query("select * from foo where x = ? and y in ??", [42, [1, 2, 3]])
              Ответить
              • отсутствие нормальной поддержки массивов/коллекций - это вообще беда sql
                немногие субд предлагают хоть что-то для этого, и поэтому работа с коллекциями из какого-нибудь jdbc это тот еще геморрой
                Ответить
              • В идеальном мире понятие "prepared statement" есть не только в обертке, но и в API базы.
                А это значит что:
                * Базе не надо будет заново каждый раз парсить запрос и строить план: она понимает что если X был 3, а стал 4 то это ТОТ ЖЕ САМЫЙ запрос.
                * База может нормально работать с кешем результатов понимая что от изменения одного значения ничего не поменяется
                * Даже в случае баги языка SqlInjection невозможен физически.

                Таким вот образом становится понятно что в идеальном мире не стоит делать свой препроцессинг.

                В реальном же мире иногда обертки просто делают sprintf и эскейп, база про стейтменты ничего не знает, и можно делать какой угодно препроцессинг
                Ответить
        • P.S. Тут, имхо, не prepared statement надо (ибо оверкилл, оверхед, да и лишнего бойлерплейта дофига), а всего лишь простой синтаксис для параметризованного запроса.

          Что-то в духе:
          $cursor = $db->query("select * from foo where x = ? and y = ?", [42, 100500]);
          Ответить
          • Параметризованный запрос это ведь вроде всего лишь обёртка над prepared statement.
            Ответить
            • Ну я сейчас про интерфейс, а не про реализацию. Как оно там внутри запилит: проинтерполирует и заэкранирует, или же подготовит и передаст параметры - всем пофиг.

              Просто в 99% случаев подготовленные запросы юзаются не по назначению - подготовили, исполнили с параметрами и вынесли. Это оверхед и куча лишней писанины, особенно в языках типа сишки, где нельзя просто так взять и передать массив параметров в execute.

              А то, что нужно в типичном коде, не вставляющем миллион строк подряд - всего лишь запрос с параметрами.
              Ответить
              • P.S. Но в языках типа сишки кроме prepare/bind/bind/bind/execute ничего и не сделать (разве что аналог sprintf'а). Я затупил :)
                Ответить
        • Может быть нанять специального Prepared Statement Engineer? Говорят, в Беркли таких готовят.

          >> Они будут экранировать, экранировать экранированное,
          А потом в базе будет восемь слешек, и все равно SQL Injection, ха-ха-ха
          Ответить

    Добавить комментарий