Webamator Blog

Защита PHP скриптов, вызываемых AJAX
MENU
Home » Сайтостроителю » Защита PHP скриптов, вызываемых AJAX

Защита PHP скриптов, вызываемых AJAX

К написанию данного поста меня побудил однотипный вопрос, задаваемый на множестве вебмастерских форумов – в том числе и на нулледе, который я модерирую и считаю лучшим из них. Если файл, который мы просто инклюдим можно “скрыть” добавлением какой-либо константы – defined(‘_BLABLABLA’) or die() то с файлами, вызываемыми XMLHttpRequest ситуация немного иная.

Сначала оговорки:
1. Вопрос “зачем это нужно” обсуждать не планирую – если вы не знаете “зачем” то вряд ли вам будет интересно “как”
2. Описываю, как делаю сам и не претендую на гениальность – если есть идеи/замечания/пожелания как сделать лучше, добро пожаловать в комментарии.
3. В примерах не будут использоваться сторонние библиотеки вроде jQuery, и сами примеры будут немного в “сокращенном” виде

Итак, вначале “простой” пример:

function ajax (get_var) {
    var xml_http = null;
    if (window.XMLHttpRequest){
        xml_http = new XMLHttpRequest();
    }
    else if (window.ActiveXObject){
        try{
            xml_http = new ActiveXObject("Msxml2.XMLHTTP");
            }
        catch(e){
            try{
                xml_http = new ActiveXObject("Microsoft.XMLHTTP");
            }
        catch(e){}
        }
    }
    xml_http.open("GET", "myfile.php?mycmd=" + get_var, true)
    xml_http.onreadystatechange = function() {
        if (xml_http.readyState == 4) {
            document.getElementById("feld").innerHTML = xml_http.responseText
        }
    }
    xml_http.send(null)
}

Здесь мы вызываем файл myfile.php, в который будем передавать mycmd=”какое-то значение”. Вроде все работает, myfile.php в зависимости от полученного значения выполняет то или иное действие, и… можно бежать сдавать заказчику? Не совсем – принцип “вроде все работает” неприемлим в веб-разработке (да и вообще в разработке). Сейчас к myfile.php можно обратиться напрямую из адресной строки браузера – и если он выполняет относительно простые действия вроде подсчета голосования то ничего страшного сайту не грозит (максимум – это накрутят голосов какой-нибуть “мисс-очередной-конкурс” ), но ведь myfile.php может служить и для другого…

Самое первое (и самое простое) – проверить как вызывается файл:

if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) or ($_SERVER['HTTP_X_REQUESTED_WITH']) != ''XMLHttpRequest')//что-то не так, это не ajax-запрос

Тем не менее, нельзя назвать данный способ универсальным – например посетитель пришел через корпоративный прокси, режущий “незнакомые” заголовки. К тому же заголовки можно подделать.

Следующее – это добавить проверку реферера, т.е. откуда вызывается файл. Немного изменим вызов файла:

xml_http.open("GET", "myfile.php?mycmd=" + get_var path=" + window.location.pathname, true)

а в myfile.php делаем примерно так:

$safe_path = $_GET['path'];
$pattern='/http\:\/\/((www\.)?[^\/]+)(.+)$/';
preg_match($pattern, $_SERVER['HTTP_REFERER'], $output);
$safe_host = $output[1];
$safe_referer = $output[3]; 

if($safe_host != $_SERVER['SERVER_NAME'])//не тот домен
if(empty($safe_path) or $safe_path != $safe_referer)//не тот путь

Однако и путь и домен можно подделать, т.е. так же как и в первом случае, считать это универсальной защитой по крайней мере наивно. Что можно проверить еще?

Можно в вызывающем файле добавить сессию, а в вызываевом проверять ее соответствие.
Для этого добавим в вызывающий файл строки:

session_start();
$_SESSION['safe'] = md5(time().'blablabla');
$demo_s = $_SESSION['safe'];

вместо blablabla можете подставить свое значение – например ид/логин/емайл посетителя. И снова немного изменим наш вызов:

xml_http.open("GET", "myfile.php?mycmd=" + get_var path=" + window.location.pathname + "<?php print '&mykey='.$demo_s;?>", true)

А в myfile.php добавим такую проверку:

session_start();
$safe_session = $_GET['mykey'];
if(empty($safe_session) or $safe_code != $_SESSION['safe'])//что-то не так с сессией

В примерах специально не указано никаких действий в случае “неправильного” обращения к файлу – как поступать, вы должны решать сами в каждом конкретном случае – прерывать работу скрипта, выдавать сообщение об ошибке, писать в лог и т.д.

Если использовать все три проверки одновременно, то будете иметь достаточно высокую степень защиты от вызова файла “извне”. Однако не стоит полагаться лишь на эти проверки. Если вызываемый файл, например, записывает данные в базу, эти данные также нуждаются в проверке. Если вызываемый файл загружает что-то (например картинку или архив) на сервер – обязательно нужно проверять это “что-то”. Т.е. не забывайте о самом главном правиле – все что приходит извне потенциально опасно.

Вобщем, желаю всем безопасного кодинга и богатых невредных клиентов, и да пребудет с вами сила ;)
А если что-то непонятно – спрашивайте в комментариях.

Popularity: 12%

Добавлено 26 мая 2012
Рубрика: Сайтостроителю
Метки: ,

Если данный пост показался вам полезным или интересным, нажмите на одну из кнопок ниже - от vkontakte, facebook, tweeter или google+, чтобы о нем узнали ваши друзья. Спасибо!

Также рекомендую публикации, похожие на "Защита PHP скриптов, вызываемых AJAX"

Single Load Only. Избавляемся от дублирования js

В данной статье я расскажу об одной из проблем Wordpress – повторному подключению javascript. Подключение скрипта несколько раз приводит к его повторному выполнению, т.е. страдает производительность. Кроме того, [...]

Интернационализация плагинов Wordpress

Итак, предположим мы написали некий плагин, который уже успешно работает. Один из способов сделать его более популярным – это добавить возможность перевода на другие языки. Интернационализация и транслитерация. Для начала [...]

Настраиваемое лого в шаблоне WordPress

Многие премиум-шаблоны WordPress имеют страницу настроек шаблона, которая является весьма удобным инструментом для тех, кто не знаком с языками разметки или программирования. Как правило, на странице настроек можно изменить [...]

jQuery для ускорения работы сайта

На первый взгляд, довольно странная фраза – как может дополнительная библиотека, которую многие используют исключительно для “украшательств” и визуальных эффектов, ускорить работу сайта? Особенно если вспомнить о ее [...]

1 комментарий

  • Константин пишет:

    Меня интересует данный вопрос, о защите загружаемых файлов при ajax запросе. Как сейчас вы делаете защиту для этих целей? Ведь с момента написания статьи прошло 9 июня 2014 минус 26 мая 2012 = 2 года)

1 комментарий


RSS feed for comments on this post.

Leave a comment