"PHP" / Говнокод #2220 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
function post($key)
{
	return mysql_escape_string($_POST[$key]);
}

$sql->Query("SELECT `t1`.*, `t2`.* 
			FROM `x_local_users` AS `t1`, `x_privs` AS `t2` 
			WHERE `t1`.`id`=`t2`.`manager_id` 
			AND `t1`.`login`='".post('userid')."'
			AND `t1`.`password`='".md5(post('passw'))."' LIMIT 1");

Где то когда то здесь видел кусок "говнокода", в котором для получения значения глобальных переменных использовались функции.
Решил на деле испытать такой способ. Очень удобно оказалось использовать, особенно в запросах :)

Единственное, что не удобно, так это когда в $_SESSION хранится двухмерный массив, и из него вытащить надо чонить =)

Запостил: nolka4 nolka4, (Updated )

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

  • Ну... Я предпочитаю примерно так:
    function gpc($var, $defval = null)
    {
      if (strlen($var) < 2) return $defval;
      switch ($var{0})
      {
        case 'G': $sg = &$_GET; break;
        case 'P': $sg = &$_POST; break;
        case 'C': $sg = &$_COOKIE; break;
        default: return $defval;
      }
      $key = substr($var, 1);
      $value = (isset($sg[$key])) ? (MAGIC_QUOTES ? stripslashes($sg[$key]) : $sg[$key]) : $defval;
      if (is_int($defval)) $value = intval($value);
      return $value;
    }

    Примеры:
    gpc('Gtest') - возвращает $_GET['test'] или NULL, если такая переменная не передана;
    gpc('Pmessage', '') - $_POST['message'] или пустая строка (аналогично);
    gpc('Ppost_id', 0) - $_POST['post_id'], принудительно приведённый к целому типу, или 0.
    > А чем $_POST не устраивает?
    Тем, что использование таких вот функций-обёрток упрощает работу с $_POST, позволяя не писать длинных строк типа
    $message = isset($_POST['message']) ? $_POST['message'] : '';
    Ответить
    • Ну да не приходится писать длинных строк, только потом втыкай в ваши Gtest и пр. при чтении таких вот проектов. Плюс время выполнения растет при использовании таких вот оберток, и главное почему? А по тому, что лень писать...
      Ответить
      • пишите на асме сразу, раз так беспокоитесь о времени. В моем примере используется стандартный вариант с экранированием переменной, который ни чуть не медленнее обычного кода без таких сокращений. Или вы не экранируете значения переменных в запросе?
        Ответить
        • Я не экранирую 🙂 Экранирует библиотека для работы с BD, с прямыми SQL запросами я уже года полтора как не работаю
          Ответить
          • ну вот, а еще жалуетесь на производительность оберток 🙂
            Ответить
            • Да я не жалуюсь я их не использую 🙂 Экранирование данных производится уже в вызове метода который строит запрос к БД Во всех остальных случаях работа ведется с переменными напрямую
              Ответить
      • Для начала скажу о примере обёртки, который я привёл (gpc). Во-первых, весь код комментируется и документируется, так что о назначении догадаться можно. Во-вторых, такого рода обёртка - это одна из часто применяемых низкоуровневых функций, так что при чтении проекта кем-то чужим этот кто-то практически сразу столкнётся с необходимостью залезть в код/документацию и посмотреть, зачем эта функция нужна и как ей пользоваться. Далее, количество переменных, принимаемых из формы, не так уж и велико, поэтому время, затрачиваемое на приём данных с помощью обёртки, оказывается в среднем в несколько десятков раз меньше, чем время выполнения всего остального кода, включающего такие вкусности, как запросы к БД или, может быть, генерацию/обработку изображений (и профилирование это наглядно показывает). По поводу библиотеки для работы с БД: конечно же, без placeholder'ов никуда, и они дают ещё один эшелон защиты. Но я не призываю использовать обёртки (а точнее, возможность приведения типов с их помощью) в первую очередь для защиты от инъекций - фильтрация или валидация данных бывают нужны ещё в массе случаев.

        И да, пора уже высказаться насчёт собственно говнокода. Автору следует задуматься о следующих вещах:
        1) функция mysql_escape_string() is deprecated и в скором времени будет выпилена из PHP. Авторы PHP рекомендуют mysql_real_escape_string() в качестве более надёжной замены.
        2) называть функцию приёма данных из формы И их экранирования просто post - это действительно не лучшая идея. Кто-то чужой, кто положится на смысл названия, может долго удивляться, почему у него вылезают лишние слэши, пока не залезет в код и не узрит тело функции.
        3) а вообще, как отметили выше, писать экранирующую обёртку действительно на хрен не упало, потому что есть плейсхолдеры. Так что пункт 1 тут лишний - при нормальном написании об этих эскейп стрингах думать вообще не приходится, это всё забота библиотеки.
        Ответить
        • Вы сейчас экранируете не подумав о том, что этого делать на этом уровне логики нельзя. Подготавливаете для sql? Ну так и экранируйте именно при составлении sql/отправки для конструктура и прочего, ваша мега-обёртка будет работать с PostgreSQL?
          Ответить
          • Обращаю внимание, что обёртка, которую я привёл (gpc), используется для извлечения данных из переменных типа $_POST, но не для экранирования при подстановке в запрос. Про разделение уровней логики я прекрасно понимаю, всему должно быть своё место. Хотя мой прокол в том, что я явно не указал в комментарии к gpc назначение этой обёртки - многие не вчитываются в код и судят по ОП-посту.
            Ответить
    • выпей йаду
      залогинился бы только чтоб заминусовать аффтара кода и аффтара комента.
      Ответить
      • Как обоснованно, обстоятельно и аргументированно. Батя грит маладца.
        Ответить
        • - а если нужно получить именно то, что передано (без экранирования и т.д.)? - костыль
          - а если самому нужно положить в массив какую-нибудь переменную ?? - костыль

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

          ps. если эти примеры взяты из книжки, то к ней должен прилогаться пузырёк с йадом
          Ответить
          • - а если нужно получить именно то, что передано (без экранирования и т.д.)? - костыль
            Если ты про говнокод, то 100% прав. А вон то gpc вообще немножеко не о том, это вещь просто для доставания переменных из формы, а не подстановки в запрос.
            - а если самому нужно положить в массив какую-нибудь переменную ?? - костыль
            В какой массив?
            не пробовали реализовать в виде статического класса? и нормально реализовать необходимые возможности в нём.
            Не буду разводить срачь между фанатами и противниками ООП и промолчу.
            Ответить
          • когда я писал этот код, я думал только об экранировании переменных для запросов. Если бы нужно было что то другое - сделал бы что то другое 🙂
            Ответить
            • экранировать нужно, только если ты куда-то сохраняешь, или выводишь или где нить ещё, где можно чего-нибудь сломать
              Ответить
  • Собственно говно здесь:
    [code language=php]md5(post('passw'))[/code]
    - в этом случае экранировать не надо было
    Ответить
    • ага, ебашим в запрос неэкранированный юзеринпут!
      Ответить
      • а хотя да, есть что то в ваших словах правдивое. туда ж в итоге придет хэш от того что ввели, а не сам пасс 🙂
        Ответить
        • Именно. А хэш описывается выражением /[0-9a-f]{32}/, там попросту нету опасных символов.
          Ответить
          • но с другой стороны, это может быть своебразной солью 🙂
            Ответить
                • Что ж, полагаю, суть просаливания хэшей из этой статьи ты уяснил. Отмечу, что в ней содержится одно корявенькое утвержедние:
                  > Как правило, SALT - это строка из 4...8 случайных символов, которая <...> сохраняется вместе с финальным хэшем (как, к примеру, сделано в MD5 (Unix)-хэшах)
                  Обрати внимание на подчёркнутое. Unix crypt() действительно автоматически просаливает хэш и прикрепляет соль к солёному хэшу. Но для MD5 это неверно! MD5 даёт однозначное соответствие между строкой и её хэшем, поэтому просаливать MD5-хэши надо самому. Навскидку:
                  define('SALTLEN', 16);
                  
                  function md5salt($pass)
                  {
                    $salt = '';
                    for ($i = 0; $i < SALTLEN; ++$i)
                      $salt .= chr(($x = mt_rand(48, 63)) > 57 ? $x + 39 : $x);
                    return $salt.md5($pass.$salt.$pass.$salt.$pass);
                  }
                  
                  function isHashValid($pass, $hash)
                  {
                    $salt = substr($hash, 0, SALTLEN);
                    return md5($pass.$salt.$pass.$salt.$pass) == substr($hash, SALTLEN);
                  }

                  В функцию md5() в данном случае подаётся исходный пароль, переёбанный с солью (конкретный способ переёбывания не важен - главное сделать и потом уже не трогать ничего). И да, на выходе md5salt() получается строка из hex-символов, что, опять же, безопасно для подстановки в запрос.
                  Ответить
  • пиздец сборище гениев
    кто там не работает на прямую с БД ? ОРМ используешь? флаг тебе в руки, построй-ка запрос с 3-мя джоинами в котором один будет на подселект с джоином
    и потом попробуй прочитать полученный код без взрыва мозга

    экранировать надо перед вставкой в базу или перед выводом в браузер (если данные не обязательно сувать в базу) . а всякие айдишники надо приводить к типу, блять! $q="UPDATE users SET note = 'loh' WHERE user_id = ".(int)$_GET['id'];
    идея ясна?
    жраьт говно суки! идите нахуй или на форумы и учитесь. за вами потом "проекты" ваши доделывать - ёбнуться можно
    Ответить
    • Давай ты сначала весь тред внимательно прочитаешь, о Великий, а потом поймёшь, что наговорил кучу тупых банальностей, которые тут ВСЕ прекрасно понимают. А лучше просто уйди.
      Ответить
    • ну я в своем проекте если передаю скриптам всякие целочисленные значения, то передаю их как (int)post('user_id')
      Ответить
      • Ты, надеюсь, не забываешь то, о чём уже неоднократно говорилось - что твоя функция post() выполняет экранирование для подстановки в запрос, которое совсем не всегда нужно (ты ведь не только в базу пихаешь принятые данные, но и, возможно, на экран)? И да, она ещё совсем не учитывает влияние magic_quotes_gpc. В случае, если эта опция включена на хостинге (а так очень много где), ты будешь наслаждаться лишними слэшами по полной программе. И, как уже говорилось, на хуй пошли все эти (int) и mysql_escape_вротмненоги (при подстановке в запрос, я имею в виду) - в хотя бы сколь-нибудь крупных проектах надо использовать PDO или любую другую БД-обёртку и не ебать мозги.
        Ответить
        • у меня cвой собственный сервак, и волжебные кавычки выключены 🙂

          на других проектах я такое еще не использовал. Если и буду использовать дальше - усовершенствую эти функции
          Ответить
      • Вообще, (int) приводит к типу integer, размеры которого платформозависимы.
        Максимальный integer в PHP может быть меньше максимального интежера Базы (например, в Оракле максимально число это 38 девяток, в Мускуле там тоже нехило)

        Так что правильней выходит проверять регуляркой параметры, что там содержатся одни цифры. /^\d+$/
        Ответить

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

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8