Как предотвратить междоменные запросы Ajax? - PullRequest
5 голосов
/ 14 июня 2011

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

ОБНОВЛЕНИЕ

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

Ответы [ 6 ]

4 голосов
/ 14 июня 2011

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

AСочетание методов обеспечит вам самую широкую защиту.Вы можете найти заголовок, использовать и файл .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

1 голос
/ 14 июня 2011

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

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

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

0 голосов
/ 30 мая 2019

для ответа пользователя 3491125, вы можете попробовать зашифровать маркер сеанса. У меня есть одна функция шифрования, которая может добавить уникальный ключ на основе порта пользователя 80 IP. это не надежно, но делает его более трудным для хакеров.

function encryptString($string, $action, $baseIP = 'false', $extraKey = ''){
    global $flag;

    $encryptedIP = '';

    if($baseIP){
        $encryptedIP = encryptString(strip_tags(htmlentities($_SERVER['REMOTE_ADDR'])), 'encrypt', false);
    }

    $output = false;

    $encrypt_method = "AES-256-CBC";
    $secret_key = $flag['encrypt-key'].$encryptedIP.'-'.$extraKey;
    $secret_iv = $flag['encrypt-secret'].$encryptedIP.'-'.$extraKey;

    $key = hash('sha256', $secret_key);
    $iv = substr(hash('sha256', $secret_iv), 0, 16);

    $output;

    if($action == 'encrypt'){
        $output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
        $output = base64_encode($output);
        $output = str_replace('=', '[equal]', $output);
    }else if($action == 'decrypt'){
        $setString = str_replace('[equal]', '=', $string);
        $output = openssl_decrypt(base64_decode($setString), $encrypt_method, $key, 0, $iv);
    }

    return $output;
}
0 голосов
/ 28 сентября 2016

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

0 голосов
/ 25 февраля 2015

Я знаю, что это старый пост, но в настоящее время ЕСТЬ"надежный" метод, позволяющий избежать этого, и это так же просто, как ад ... Сначала на странице, где будет сделан вызов 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...
}
?>    
0 голосов
/ 14 июня 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...