Подтвердить что ты не робот

Обнаружение Ajax в PHP и уверенность в том, что запрос был с моего собственного сайта

Я использую свой PHP-сервер для обнаружения запросов AJAX, проверяя значение в $_SERVER['HTTP_X_REQUESTED_WITH'].

Это дает мне надежное обнаружение, убедившись, что запрос выполняется с использованием методов AJAX.

Как я могу убедиться, что запрос пришел из моего собственного домена, а не из внешнего домена/робота?

www.example.com/ajax?true может позволить кому-либо сделать вызов AJAX и вырезать информацию.

Я мог бы делать сеансы для всех, кто обычно входит на мой сайт, а затем разрешает AJAX-вызовы.. но это тоже может быть подделано.

Это даже имеет значение в наши дни?

4b9b3361

Ответ 1

Позволяет вам контроллер

  • создать токен доступа
  • сохранение в сеансе для последующего сравнения

В вашем представлении

  • объявить токен доступа как переменную JS
  • отправить токен с каждым запросом

Назад в свой контроллер

  • проверить HTTP_X_REQUESTED_WITH
  • проверить токен

Проверьте эти правила безопасности от OpenAjax.
Кроме того, прочитайте статью о codinghorror.com, связанной с Энни.

Ответ 2

Вы можете проверить HTTP_REFERRER, но не все браузеры установили его. Лучший способ - написать оболочку для ваших вызовов ajax на стороне JavaScript, которая отправляет часть документа .cookie обратно на сервер - только ваш домен имеет доступ к файлу cookie. Вы можете сравнить файл cookie в заголовках запроса с файлом cookie в вызове AJAX в php.

В ответ на это "это даже важно, в эти дни" - ДА, это так! Прочтите это.

Ответ 3

Относительно вашего последнего вопроса: "В наши дни это имеет значение?" Это вопрос в каждом конкретном случае. Если запрос ajax делает то, что не требует безопасности (например, загружает последние котировки акций), то это действительно не имеет значения. ИМХО. Если запрос загружает информацию, которая должна быть защищена (например, возвращать идентифицирующую информацию или что-то делать на сервере), тогда вы должны рассматривать ее как таковую.

Я лично не использую переменные сервера, чтобы знать, когда что-то является ajax-запросом. Вместо этого я просто добавляю параметр запроса к вызову ajax (например, http://domain.com/?ajax=true). Если мне нужно защитить вызов ajax, я бы использовал те же методы, что и обеспечение регулярного запроса страницы (с использованием как клиента, так и сервера). Как отметил Лукас Оман, что-либо на стороне клиента может быть подделано. Нижняя строка не доверяет никакому запросу, даже если вы считаете, что он поступает с вашего сайта или базы данных. Всегда следуйте мантрам "вход фильтра" - выход выхода.

Ответ 4

Дэвид Уолш имеет хорошее решение

/* decide what the content should be up here .... */
$content = get_content(); //generic function;

/* AJAX check  */
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    /* special ajax here */
    die($content);
}

/* not ajax, do more.... */

Ответ 5

Действительно, самый безопасный способ сделать это - это, как вы предположили, использовать сеансы на стороне сервера, поскольку они не могут быть созданы как файлы cookie.

Конечно, кто-то все еще может захватить идентификатор сеанса, но если вы также сохраняете IP-адрес пользователя в своем сеансе и проверяете его по каждому запросу, вы можете вырвать много уловок. Только кто-то из той же локальной сети или прокси-сервера мог его захватить.

Любой другой упомянутый метод - cookie, javascript, http referer - зависит от данных на стороне клиента, который является небезопасным и всегда должен быть заподозрен в подделке, подделке, угнании и злонамеренном построении.

Ответ 6

Использовать защищенные запросы сеанса POST:

Внутри веб-страницы (например, index.php) нам нужно сохранить sessionid

<?php
// Create Session
$session = session_id();
if(empty($session)) session_start();
?>
<head>
...
<script type="text/javascript">
  sid = '<?php echo session_id(); ?>';
</script>
<script type="text/javascript" src="ajaxrequest.js"></script>
...
</head>

Запросы ajax (ajaxrequest.js)

/* simple getAjax function 
 * @param $url       request url
 * @param $param     parameter (dont use ?)
 * @param callback  function on success
 */
var spinnerid = '#spinner'; // Spinner as long ajax requests running
$(document).ajaxStart(function() { $(spinnerid).show(); });
$(document).ajaxStop(function() { $(spinnerid).hide(); });
function getAjax( url, param, callback ) {
    var data = null;
    url += "?sid=" + sid + "&" + param;
    $.ajax({
        url: url,
        method: "POST", // uncomment to use GET, POST is secured by session
        cache: false,
        async: true,
        success : function(data){
      callback(data);
    },
}

getAjax( 'http://domain.com/', 'data=foo', function( data ) {
 // do stuf with data 
 var jsonobj = eval("(" + data + ")");
 var data = jsonobj[0][ 'data' ];
});

Ответственная сторона php:

if( isset( $_GET['sid'] ) ) $client_sid = $_GET['sid'];

if( session_id() == null ) session_start();

if( session_id() != $client_sid ) {
    // noID or wrongID, redirect to mainindex
    ignore_user_abort(true);
    header( "HTTP/1.1 403 Forbidden" );
    header("Connection: close", true);
    exit;
} else {

    // get data
    if( isset( $_GET['data'] ) ) {
        $data = $_GET['data'];
    } else if( isset( $_POST['data'] ) ) {
        $data = $_POST['data'];
    } else {
        $data = null;
    }

    // do stuff with data

    // return data as json
    $resp[0]['data'] = $data; 
    print_r( json_encode( $resp ) );
}

Ответ 7

Проверьте $_SERVER['HTTP_REFERER']. Это будет работать во многих случаях, но его не следует путать с полностью защищенным решением.