Фильтрация запросов

Тема в разделе "Защита и взлом", создана пользователем Darkness, 3 окт 2013.

  1. Darkness

    Darkness Постоялец

    Регистр.:
    21 янв 2013
    Сообщения:
    146
    Симпатии:
    69
    Нигде не нашел готового решения, решил написать сам, писал под PHP 5.3
    Предлагаю обсудить код.
    PHP:
    <?php
          
    if(gc_enabled() !== true) {
                  
    gc_enable();
          }
          function 
    attackerexit() {
                  
    header("X-Attacker: Access denied");
                  echo 
    "Attacker: Access denied";
                  
    flush();
                  exit();
          }
          
    $querychrfilter = Array("\0""%00"chr(0), "1--""1++""1=0""1=1""0=1""0=0""/*""*/""0x""!=""UNION""NULL""FROM""WHERE""LIMIT""HAVING""ORDER BY""NOT");
          
    $querysqlfilter = Array("AND""OR""NOT");
          
    $queryfilter "/information_schema|SELECT\b|SELECT\(\)|COUNT\b|COUNT\(\)|AND\b|OR\b|database\(\)|group_concat\(\)|substring\(\)|mid\(\)|instr\(\)|show_source\(\)|system\(\)|exec\(\)|shell_exec\(\)|passthru\(\)|popen\(\)|proc_open\(\)|curl_exec\(\)|curl_multi_exec\(\)|fsockopen\(\)|pfsockopen\(\)|pcntl_exec\(\)|chmod\(\)|chown\(\)|chgrp\(\)|unlink\(\)|ftruncate\(\)|touch\(\)|realpath\(\)|rename\(\)|rmdir\(\)|symlink\(\)/i";
          
    $queryfilterbool = Array(falsefalse0);
          foreach(
    $querychrfilter as $cquerychrfilter) {
                  
    $queryfilterbool[0] = stripos($_SERVER['QUERY_STRING'], $cquerychrfilter);
                  if (
    $queryfilterbool[0] !== false) {
                        break;
                  }
          }
          foreach(
    $querysqlfilter as $cquerysqlfilter) {
                  
    $queryfilterbool[1] = strpos($_SERVER['QUERY_STRING'], $cquerysqlfilter);
                  if (
    $queryfilterbool[1] !== false) {
                        break;
                  }
          }
          
    $queryfilterbool[2] = preg_match($queryfilter$_SERVER['QUERY_STRING']);
          if (
    $queryfilterbool[0] !== false || $queryfilterbool[1] !== false || $queryfilterbool[2] !== 0) {
                  
    attackerexit();
          }
          unset(
    $querychrfilter$querysqlfilter$queryfilter$queryfilterbool);
    ?>
     
    Шумадан нравится это.
  2. Шумадан

    Шумадан Хабарра!!11

    Регистр.:
    6 фев 2008
    Сообщения:
    1.723
    Симпатии:
    2.100
    а что будет если есть поисковая форма в которой будут искать слово FROM скажем?
    ну тоесть запрос будет в виде: http://domain.com/index.php?s=FROM
    и почему SERVER['query_string'], а не $_REQUEST?
     
    Последнее редактирование: 3 окт 2013
  3. Darkness

    Darkness Постоялец

    Регистр.:
    21 янв 2013
    Сообщения:
    146
    Симпатии:
    69
    Тогда будет отвергнут запрос, еще как решение можно отлавливать запросы со скобками, к примеру FROM(), предварительно убрав все пробелы.
    В SERVER['query_string'] не разбитые, в оригинальном виде переданные данные, в $_REQUEST уже готовый и слегка отфильтрованный массив, обход массива создает больше нагрузку.
     
    Шумадан нравится это.
  4. Шумадан

    Шумадан Хабарра!!11

    Регистр.:
    6 фев 2008
    Сообщения:
    1.723
    Симпатии:
    2.100
    так у вас итак два обхода + стринговые операции поиска + не совсем вижу смысл фильтровать sql стейтменты в запросах, вернее ключевые слова, это же на совести кода который совершает манипуляции с базой.
    варианты в принципе есть, например: http://www.phpclasses.org/package/5413-PHP-Filter-dangerous-values-from-request-variables.html
    можно из парочки таких ещё что-то полезное взять
     
  5. Darkness

    Darkness Постоялец

    Регистр.:
    21 янв 2013
    Сообщения:
    146
    Симпатии:
    69
    Улучшенная версия.
     
    Последнее редактирование: 11 окт 2013
  6. TruLander

    TruLander Создатель

    Регистр.:
    25 ноя 2009
    Сообщения:
    18
    Симпатии:
    1
    Для php есть модуль называется mod_security, делает тоже самое, только больше)) и надежнее. Но он устанавливается непосредственно на сервер, с хостингами так не прокатит.
     
  7. Darkness

    Darkness Постоялец

    Регистр.:
    21 янв 2013
    Сообщения:
    146
    Симпатии:
    69
    Во первых mod_security модуль Apache, а не PHP.
    Во вторых mod_security фильтрует только часть того, что может данный скрипт, данный модуль по умолчанию фильтрует только system производные, так что он не надежнее.
     
  8. TruLander

    TruLander Создатель

    Регистр.:
    25 ноя 2009
    Сообщения:
    18
    Симпатии:
    1
    Ну да это модуль апача, но у этого модуля есть дополнительные правила фильтрации, с помощью которых и расширяется круг его действий. Его можно очень тонко настроить под свою систему. Он может работать точно также как и этот скрипт, фильтруя get, post запросы пользователя, предотвращая sql инъекции.

    Причем mod_security работает перед apache, как firewall, сначала он анализирует данные, после чего решает пропускать запрос к серверу или нет.
    И кстати для nginx он тоже есть.
     
    Последнее редактирование: 3 ноя 2013
  9. olivok

    olivok

    Регистр.:
    13 ноя 2012
    Сообщения:
    159
    Симпатии:
    98
    Вот, рекомендую ознакомится, ЧТО фильтрует mod_security с нормальными правилами, а потом сравнивать со скриптом
     
  10. Darkness

    Darkness Постоялец

    Регистр.:
    21 янв 2013
    Сообщения:
    146
    Симпатии:
    69
    Выгода скрипта заключается в том, что его достаточно подключить в начале скрипта и все.
    Модули надо поставить и настроить, не каждый способен поставить модуль, да и не у каждого есть возможность его поставить, например на хостинге модуль не поставишь.
    Есть еще дурная практика полагаться на левые фильтры и писать ***но код, но это отдельная история.
    mod_security работает как модуль апача, это не отдельный демон, исполняющий роль прокси, делать он может тоже самое что и скрипт, но его надо настроить, кто мешает подправить и настроить скрипт, имея в расположении все прелести PHP.
    ЗЫ: Обосрать код могут все, попробуйте написать лучше альтернативу.