Как предотвратить междоменные запросы ajax?

Как определить, вызван ли мой php-скрипт из другого домена, а другой домен делает незаконным использование моего сценария? Есть ли способ предотвратить это?

ОБНОВИТЬ

Я нашел этот вопрос на SO, но его все еще небезопасно, его можно подделать.

Solutions Collecting From Web of "Как предотвратить междоменные запросы ajax?"

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

Комбинация методов даст вам самую широкую защиту. Вы можете искать заголовок, использовать и .htaccess файл, а также использовать токены. Такой подход, основанный на всех вышеперечисленных условиях, делает его гораздо труднее использовать для веб-сервера – большинство злоупотреблений исходит от людей, пытающихся найти легкую дыру для использования. Важно помнить, что вы не можете успокоиться, потому что вы развернули «лучшую» защиту или потому, что у вас есть столько уровней защиты, что кажется невозможным взломать. Если кто-то действительно хотел, чтобы он был достаточно плохим и имел время, они найдут способ. Эти виды профилактических мер на самом деле являются лишь сдерживающими факторами, чтобы избегать ленивых, любопытных и ленивых злобных. Целевые атаки представляют собой целый отдельный класс безопасности и, как правило, в большей степени сосредоточены на проблемах безопасности на уровне сервера.

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

RewriteEngine on RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?_YOUR_DOMAIN_NAME_HERE.com [NC] RewriteRule \.(php)$ - [NC,F,L] 

Ознакомьтесь с этой статьей для получения информации об использовании системы токенов: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet

Вы можете вручную отклонить каждый запрос, чей заголовок Origin не соответствует вашему доменному имени. Однако не все браузеры отправляют заголовок Origin . В этих случаях вы можете вернуться к заголовку Referer [sic], проанализировать его и узнать имя домена и сравнить его, как указано выше.

Некоторые фреймворки JavaScript также устанавливают заголовок X-Requested-With для запросов AJAX.

Это должно отклонить значительный процент пользователей (я бы оценил> 95%). Обратите внимание, что из -за политики одинакового происхождения , единственное, что парень, отправляющий запросы AJAX в ваш домен, получает информацию о синхронизации в любом случае.

Немного похоже на user3491125, вы можете установить $ _SESSION на странице, где выполняется вызов, и проверить ее на странице Ajax, если существует, например, $ _SESSION ['user'].

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

Невозможно создать систему, открытую для пользователей, но не скрипты без входа / раздражения.

Я знаю, что это старый пост, но в настоящее время существует «надежный» метод, чтобы избежать этого и его просто, как черт … Сначала на странице, где будет сделан вызов ajax:

 <?php $token = sha1(rand(1000,9999)); $_SESSION['token'] = $token; ?> 

Затем в сценарии ajax

 var formData = new FormData(); formData.append("token","<?php echo $token;?>"); $.ajax({ url: 'yourfile.php', type: 'POST', xhr: function() { var myXhr = $.ajaxSettings.xhr(); return myXhr; }, success:function(data) { alert(data); }, data: formData, cache: false, contentType: false, processData: false }); 

И, наконец, на странице php, которая будет называться:

 <?php $token = $_POST['token']; if($token === $_SESSION['token'] && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') { //Perform your stuff here... } ?>