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

Discussion in 'Статьи' started by GreenBear, 25 Mar 2007.

  1. GreenBear

    GreenBear наркоман с медалью

    Joined:
    7 May 2005
    Messages:
    2,547
    Likes Received:
    1,398
    Reputations:
    612
    Начинаем веб-программирование не падая лицом в грязь.

    В статье примеры будут на php, как на самом популярном языке среди программирования для веб.

    Нужно обрабатывать все данные, которые как либо будут участвовать в sql-запросах, которые будут участвовать в открытии файлов, выводится на страницу. Не надо забивать даже на мелкие детали – это лишь увеличит ваше «забей» в дальнейшем.​

    SQL-Injections​


    Давайте рассмотрим простой пример:
    PHP:
    $id  $_REQUEST['id'];
    $result mysql_query("SELECT title, text, dateline, autor FROM `news` WHERE `id`='$id'");
    Хм, что-то не так, не правда ли? Если вы не заметили, то поздравляем – в вашем проекте sql-injection, которая может привести даже к дефейсу сайта.
    Этого не было бы, если бы вы обработали сразу переменную.
    PHP:
    $id mysql_escpape_string($_REQUEST['id']);
    Более подробно с функцией mysql_escape_string можно ознакомится на сайте php.net

    Но если значение id может быть только целым числом, зачем вообще допускать другие символы? Незачем.

    Может быть так будет лучше:
    PHP:
    if(!is_numeric($_REQUEST['id'])){
        
    //тут сообщение об ошибке о некорректных данных
    }else{
        
    //если значение является целым числом, то можем продолжать без дальнейшей фильтрации за бесполезностью
    }
    А можно и вырезать все лишнее функцией intval
    PHP:
    $id intval($_REQUEST['id']);
    if(
    $id){
        
    //можно продолжать
    }else{
        
    //айди равно нулю

    Есть мнение, и я думаю оно правильное: перед вносом в базу данных не надо обрабатывать никакие значение на вырез плохих кодов, это надо делать при выводе. В БД надо правильно вносить данные.

    mysql_escape_string и mysql_real_escape_string именно для этого и созданы.

    SQL-Injections нас уже не побеспокоят, перейдем дальше.

    Вывод данных.​

    XSS это бич практически любого динамического сайта в Интернете. А все почему? Да потому что не многие считают это опасной уязвимостью (что очень и очень зря), и то, что просто забывают о том, что вместо ?page=1 злоумышленник может написать ?page=<script>evil_code</script>, который выведется на страницу.
    Как обезопасится? Так же, как и в первом случае: фильтровать все данные, которые так или иначе будут выводится на странице. Тут могу порекомендовать такой же совет, как и в случае защиты от sql-inj – если значение может быть только int, то и не надо допускать другого!

    В php есть несколько функций, которые вырезают html теги:
    htmlspecialchars,
    htmlentities,
    strip_tags

    Все данные, которые будут выводится на страницу должны быть отфильтрованы! Иначе безопасность вас и посетителей сайта может быть под угрозой.

    Инклудинг файлов.​

    Из-за некорректности кода могут возникнуть и более серьезные угрозы безопасности вашего сайта, чем в предыдущем случае.
    Часто из-за недостаточной обработке данных на сайтах присутствует возможность инлкуда локальных или удаленных файлов.

    Если вы используете конструкцию типа приведенной ниже:
    PHP:
    $file $_REQUEST['file'];
    include(
    $file.'.html');
    то поздравляю – у вас инклуд-уявзвимость.
    А что если мы подставим в файл http://evilhost.com/shell.php?
    Правильно, на вашем сайте будет шелл :)

    Как защитится? Опять же – проверять данные, переданные скрипту.
    Скорее всего вам не понадобится никакие название файлов, кроме как из маски a-z
    Давайте проверим переменную файл регулярным выражением, и если она пройдет проверку, то мы ее и передадим:
    PHP:
    if(preg_match('/[a-z]/i'$file)) include($file.'.html');
    else echo 
    'Это не правильный файл!';
    Если предпологается, что файлы не будут добовлятся динамически и их относительно не много, то лучше использовать функцию switch
    Пример:
    PHP:
    switch($_REQUEST['file']){
        case 
    'eto': include('files/eto.html'); break; // Если файл – eto, ниже соотвественно
        
    case 'tolko': include('files/tolko.html'); break;
        case 
    'na4alo': include('files/na4alo.html'); break;
        default: 
    //То, что будет, если ни одно вышестоящие условие не выполнено
        
    echo 'А страница-то пустая :)';
        break;
    }

    Кстате, вы можете грузить одну и туже страницу по нескольким именам:
    PHP:
    switch($file){
        case 
    'eto':
        case 
    'tolko':
        include(
    'files/eto.html');
        break;
        
    //
    }
    Помните, что обрабатыватся должны абсолютно все данные участвующие в сценарии. Будь то файл cookie, в котром хранятся данные о папке языка, будь то название шаблона.

    Readfile or include?
    Если в файле не планируется исполнения кода, то можно пользоватся функцией file_get_contents или readfile.

    Например:
    PHP:
    echo file_get_contents('files/'.$file.'html');
    //or
    readfile('files/'.$file.'.html');
    Это также обезапасит вас, если вы создаете файлы динамически из админ-центра.
    Ведь если злоумышленик получит доступ в админ-панель, а там создаст страницу с плохим кодом, то для вас это будет не менее печально, чем если бы был инклудинг файлов.
     
    9 people like this.
  2. blaga

    blaga Elder - Старейшина

    Joined:
    23 Mar 2006
    Messages:
    884
    Likes Received:
    273
    Reputations:
    106
    Неплохо вроде...) Насчет SQL-Injections неплохо написал nerezus вот здесь https://forum.antichat.ru/thread30641.html там целая тема по тому же способу что ты описал...
    Рекомендую к прочтению как в добавку к этой статье.
     
  3. banned

    banned Banned

    Joined:
    20 Nov 2006
    Messages:
    3,324
    Likes Received:
    1,193
    Reputations:
    252
    Так все хорошо, но начало....(Защита от sql-inj) я бы поправил....
    Правильней было бы сделать так:
    PHP:
       if (!get_magic_quotes_gpc()) {
       
    $id mysql_escape_string($_REQUEST['id']);  
       } else {
       
    $id $_REQUEST['id']
       }
    Это сделано для правильного вывода защиты....т.е. если у нас есть магия, а мы все равно делаем mysql_escape_string, то вывод будет не 1 кавычкой, а четыремя....вот и код не красивый получился бы :)

    А так молодец....+ 3
     
    #3 banned, 25 Mar 2007
    Last edited: 25 Mar 2007
  4. GreenBear

    GreenBear наркоман с медалью

    Joined:
    7 May 2005
    Messages:
    2,547
    Likes Received:
    1,398
    Reputations:
    612
    я просто стараюсь держаться подальше от блядских серверов, чего и всем советую
     
    3 people like this.
  5. nerezus

    nerezus Banned

    Joined:
    12 Aug 2004
    Messages:
    3,191
    Likes Received:
    729
    Reputations:
    266
    предпочтительно поковырятться в конфиге сервера и отключить эту пакость.
    Радует, что ее не будет в PHP6.