2009-11-18 4 views
30

Я звоню код PHP с AJAX, как это:Предотвращение прямого доступа к файловому Вызывается АЯКС Функция

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

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

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

Также я пробовал решение posted here, но его не работает для меня - всегда получайте сообщение «Непрерывный доступ».

+0

Итак, вы в основном хотите, чтобы ваш скрипт был доступен через AJAX, но не если я набираю URI? –

+0

да, это именно так – jriggs

+0

Есть ли причина, по которой вы не можете использовать .htaccess, описанные в ссылке, которую вы опубликовали? –

ответ

39

Большинство запросов/фреймворков 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 следующего в вашем яваскрипте кода:

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

Хотя это не на 100% эффективнее (в случае, если заголовки подделаны), это очень быстрое и простое решение, позволяющее только называть AJAX на страницу. +1 –

+0

А ... это тип решения, которое я ожидал получить. К сожалению, я не использую никаких фреймворков - просто прямо javascript/ajax. Любая ставка, переменная не установлена ​​с моим кодом, поэтому это не работает для меня. – jriggs

+0

Я пытаюсь реализовать это с помощью Google Maps, вызывающего скрипт php, который возвращает данные XML. Однако GDownloadUrl («», Функция (данные) {var xml = GXml.parse (data); (...))} не позволяет мне определить тип ответа таким образом в моем PHP-скрипте. – richey

7

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

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

+0

Спасибо - это похоже на излишний мой сценарий. Страница, которую я вызываю, просто отправляет электронное письмо - передаваемый параметр является адресом электронной почты. Я действительно только задал этот вопрос, потому что Im все еще довольно новичок в ajax, и это похоже на то, что может быть проблемой в будущих приложениях. – jriggs

0

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

От того, я предложил бы использовать печенье:

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

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

10

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

4

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

+0

Потому что боты и хакеры, скребки, ddosers, интернет - неприятное место, которое вы им даете, и люди будут пытаться использовать его, чтобы уничтожить вас. –

0

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

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

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

2

Любой, кто в этой теме, который предложил посмотреть заголовки, в той или иной мере ошибочен. Все, что содержится в запросе (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, а также только для аутентифицированных пользователей. Если кто-то нападает на это, это означает, что у вас есть учетная запись, и вы хотите закрыть эту учетную запись.

1

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

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

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

1

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

  1. проверка реферер $ _SERVER [ 'HTTP_REFERER'];
  2. проверить http x request $ _SERVER ['HTTP_X_REQUESTED_WITH'];
  3. проверить происхождение с помощью файла моста

если все три прохода, вы успех в том, чтобы файл PHP называет AJAX, если только один сбой вы не получите это

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

Bridge файл

Immagine следующий сценарий:

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

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

    данных моста = «ehfwiehfe5435ubf37bf3834i»

  • 4), этот ваяемый код retrived Из JavaScript и отправляется через Ajax запрос сообщения в B.php

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

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

0

Я попытался это

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. Но потом решил, что скрытое поле ввода не обязательно, потому что может отправить без него

-2

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