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

Предотвращение прямого доступа к файлу, вызываемому функцией ajax

Я вызываю код php из ajax так:

ajaxRequest.open("GET", "func.php" + queryString, true);

Так как это запрос get, любой может увидеть его, просто изучив заголовки. Передаваемые данные не являются конфиденциальными, но потенциально могут быть использованы неправильно, так как это также тривиально получить имена параметров.

Как я могу запретить прямой доступ к http://mysite/func.php и разрешить доступ к моей странице ajax?

Также я попробовал опубликованное здесь решение, но оно не работает для меня - всегда получаю сообщение "Прямой доступ не разрешен".

4b9b3361

Ответ 1

Большинство запросов/фреймворков Ajax должны устанавливать этот конкретный заголовок, который вы можете использовать для фильтрации Ajax v Non-ajax-запросов. Я использую это, чтобы определить тип ответа (json/html) в большом количестве проектов:

if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )
{
    // allow access....
} else {
    // ignore....
} 

изменить: Вы можете добавить это самостоятельно в свои собственные запросы Ajax со следующим кодом javascript:

var xhrobj = new XMLHttpRequest();
xhrobj.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 

Ответ 2

то, что я использую: PHP-сессии + хэш, который отправляется каждый раз, когда я делаю запрос. Этот хэш генерируется с использованием некоторого алгоритма на стороне сервера

Ответ 3

Mmm... вы можете создать одноразовый пароль при запуске сеанса, который вы могли бы сохранить в _SESSION, и добавить параметр к вашему вызову ajax, который будет повторно передавать это (что-то вроде captcha). Он будет действителен только для этой сессии.

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

Ответ 4

Я хотел бы спросить, почему вы так уверены, что никто не сможет посетить этот файл напрямую. Ваше первое действие на самом деле должно состоять в том, чтобы предположить, что люди могут посетить страницу напрямую и обойти эту возможность. Если вы по-прежнему убеждены, что хотите закрыть доступ к этому файлу, вам следует знать, что вы не можете доверять переменным $_SERVER для этого, поскольку трудно определить происхождение $_SERVER и подделать значения заголовков. В некоторых тестах я обнаружил, что эти заголовки ($_SERVER['HTTP_X_REQUESTED_WITH'] & $_SERVER['HTTP_X_REQUESTED_WITH']) также ненадежны.

Ответ 5

Любой в этой теме, который предложил посмотреть на заголовки, так или иначе ошибочен. Все, что содержится в запросе (HTTP_REFERER, HTTP_X_REQUESTED_WITH), может быть подделано злоумышленником, который не является полностью некомпетентным, включая общие секреты [1].

Вы не можете запретить пользователям делать HTTP-запрос на ваш сайт. То, что вы хотите сделать, это убедиться, что пользователи должны пройти аутентификацию, прежде чем отправлять запрос на какую-либо чувствительную часть вашего сайта, используя cookie сеанса. Если пользователь делает неавторизованные запросы, остановитесь прямо там и дайте им HTTP 403.

Ваш пример делает запрос GET, поэтому, я думаю, вы обеспокоены требованиями к ресурсу запроса [2]. Вы можете сделать некоторые простые проверки работоспособности в заголовках HTTP_REFERER или HTTP_X_REQUESTED_WITH в ваших правилах .htaccess, чтобы остановить появление новых процессов для явно поддельных запросов (или тупых поисковых искателей, которые не будут слушать robots.txt), но если злоумышленники подделывают тем, вы захотите, чтобы ваш PHP-процесс завершался как можно раньше для неидентифицированных запросов.

[1] Это одна из основных проблем с клиент-серверными приложениями. Вот почему это не работает: скажите, что у вас есть способ для вашего клиентского приложения аутентифицироваться на сервере - будь то секретный пароль или какой-либо другой метод. Информация, необходимая для приложения, обязательно доступна для приложения (пароль скрыт где-то там или где угодно). Но поскольку он работает на пользовательском компьютере, это означает, что они также имеют доступ к этой информации: все, что им нужно, - это посмотреть на источник, или на двоичный, или на сетевой трафик между вашим приложением и сервером, и в конечном итоге они выяснят механизм аутентификации вашего приложения и его тиражирование. Возможно, они даже скопируют его. Может быть, они напишут умный взломать, чтобы ваше приложение сильно поднялось (вы всегда можете просто отправить поддельный пользовательский ввод в приложение). Но как бы то ни было, у них есть вся необходимая информация, и нет способа остановить их от ее использования, что также не помешает вашему приложению иметь ее.

[2] Запросы GET в хорошо спроектированном приложении не имеют побочных эффектов, поэтому их никто не сможет внести изменения на сервере. Ваши POST-запросы всегда должны быть аутентифицированы с помощью токена CESF, а также только для аутентифицированных пользователей. Если кто-то атакует это, это означает, что у вас есть учетная запись, и вы хотите закрыть эту учетную запись.

Ответ 6

Я решил эту проблему, готовя функцию проверки, которая делает три вещи

  • check referer $_SERVER ['HTTP_REFERER'];
  • проверить http x request $_SERVER ['HTTP_X_REQUESTED_WITH'];
  • проверить происхождение через файл моста

Если все три пройдут, вам удастся увидеть файл php, вызванный ajax, если только один из них не получается, вы не получите его

Точки 1 и 2 уже были объяснены, решение для файла моста работает так:

Файл моста

импортируйте следующий сценарий:

вызов страницы A.php через ajax B.php, и вы хотите запретить прямой доступ к B.php

  • 1), когда загружается страница A.php, он генерирует сложный случайный код
  • 2) код копируется в файл C.txt, который напрямую не доступен из web (httpd обеспечен)
  • 3), в то же время этот код находится в ясной скульптуре в визуализированном html страницы A.php(например, как атрибут тела, es:

    данных моста = "ehfwiehfe5435ubf37bf3834i"

  • 4) этот вылепленный код извлекается из javascript и отправляется через ajax отправить запрос на B.php

  • 5) Страница B.php получает код и проверяет, существует ли он в файле C.txt
  • 6), если код соответствует коду, выскочил из C.txt и на странице B.php доступно
  • 7), если код не отправлен (если вы попытаетесь получить доступ непосредственно к B страница) или совсем не совпадают (если вы поставили старый код в ловушке или трюк с помощью специального кода), страница B.php умирает.

Таким образом, вы можете получить доступ к странице B только через вызов ajax, созданный на странице отца A. Ключ для pageB.php предоставляется только и всегда из pageA.php

Ответ 7

Поместите следующий код в самый верх вашего php файла, который вызывается ajax. Он выполнит запросы ajax, но "умрет", если вызывается непосредственно из браузера.

define('AJAX_REQUEST', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
if(!AJAX_REQUEST) {die();}

Лично я предпочитаю не выводить ничего после "die()" в качестве дополнительной меры безопасности. Это означает, что я предпочитаю показывать только "пустую" страницу "злоумышленнику", а не давать подсказки, такие как "если" или "почему" эта страница защищена.

Ответ 8

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

Из этого я бы предложил использовать файлы cookie:

Просто setcookie() на странице, использующей AJAX, и проверьте $_COOKIE на правильные значения на func.php. Это даст вам некоторую разумную уверенность в том, что кто-либо, вызывающий func.php, недавно посетил ваш сайт.

Если вы хотите стать более привлекательным, вы можете установить и проверить уникальные идентификаторы сеанса (вы можете сделать это уже) для гарантии того, что cookie не подделывается или не подвергается насилию.

Ответ 9

Нет смысла делать это. Он не добавляет никакой реальной безопасности.

Все заголовки, указывающие, что запрос выполняется через Ajax (например, HTTP_X_REQUESTED_WITH), могут быть скопированы на стороне клиента.

Если ваш Ajax обслуживает конфиденциальные данные или разрешает доступ к конфиденциальным операциям, вам необходимо добавить надлежащую безопасность, например, систему входа.

Ответ 10

Я пробовал это

1) в основном php файле (из которого отправлен запрос ajax) создать сеанс с некоторым случайным значением, например $_SESSION['random_value'] = 'code_that_creates_something_random'; Обязательно убедитесь, что этот сеанс создан выше $.post.

2), то

$.post( "process_request.php", 
{ 
input_data:$(':input').serializeArray(),
random_value_to_check:'<?php echo htmlspecialchars( $_SESSION['random value'], ENT_QUOTES, "UTF-8"); ?>' 
}, function(result_of_processing) {
//do something with result (if necessary)
});

3) и в process_request.php

if( isset($_POST['random_value_to_check']) and 
trim($_POST['random_value_to_check']) == trim($_SESSION['random value']) ){
//do what necessary
}

Прежде чем я определил сеанс, затем скрытое поле ввода с значением сеанса, затем значение скрытого поля ввода отправит с помощью ajax. Но потом решил, что скрытое поле ввода не обязательно, потому что может отправить без него

Ответ 11

У меня есть упрощенная версия решения Edoardo.

  1. Веб-страница A создает случайную строку [token] и сохраняет файл с таким именем на диске в защищенной папке (например, с .htaccess и Deny from all на Apache).

  2. Страница A передает [token] вместе с AJAX-запросом в сценарий B (в OP queryString).

  3. Скрипт B проверяет, существует ли имя файла [token] и если это так, то оно продолжается с остальной частью скрипта, в противном случае завершается.

  4. Вам также понадобится настроить скрипт очистки, например. с Cron, чтобы старые токены не накапливались на диске.

Также полезно сразу же удалить файл [token] со скриптом B, чтобы ограничить количество запросов.

Я не думаю, что проверка заголовков HTTP необходима, поскольку она может быть легко подделана.

Ответ 12

Я пробовал много предложений, никто не решил проблему. Наконец, я защитил параметры файла целевого файла php, и это был единственный способ ограничить прямой доступ к файлу php. ** Puting php file и set limit by.htaccess вызвали сбой Ajax-соединения на главной странице Html.