Как защитить доступ к URL?

#php #security

#php #Безопасность

Вопрос:

Мне нужно было бы создать php-файл, который будет выполнять некоторую работу на моем веб-сервере и который будет вызываться из программы на другом сервере через Интернет. Предположим, php-файл, который будет выполнять работу, расположен по адресу www.example.com/work.php

Какой наилучший способ защитить незапрошенные вызовы к www.example.com/work.php ?

Что мне нужно, так это некоторый механизм, чтобы, когда предполагаемая программа обращается к URL (с некоторыми параметрами строки запроса), работа была выполнена, но если кто-нибудь введет www.example.com/work.php в их браузере доступ будет запрещен, и никакая работа выполняться не будет.

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

 ?key=randomKeyAtEachCallamp;token=SomeHexadecimalResultCalculatedFromTheKey
  

и ключ и токен будут проверены с помощью обратного алгоритма на стороне php.

Безопасно ли это, есть ли идея получше?

Комментарии:

1. Извините, я неправильно истолковал ваш вопрос. Я не знал, что это было между серверами. В таком случае вам нужно что-то вроде этого httpd.apache.org/docs/1.3/mod/mod_access.html . Тогда вы можете написать правила на своем веб-сервере вместо дополнительного кода и большего раскрытия вашего приложения.

2. @stevebot: не могли бы вы предоставить больше информации в форме ответа, пожалуйста?

3. @stevebot: да, точно… зачем удалять ваш первоначальный ответ и отклонять ответ Crontab, который был полезен?

4. потому что я неправильно истолковал вопрос. Я бы не стал использовать сеанс в этом случае, потому что это межсерверное взаимодействие, а не от клиента. И я не понял, что Crontab ответил именно так, потому что это ТАК, а не ServerFault, что имеет некоторый смысл.

Ответ №1:

Вы можете попробовать несколько вариантов!

Сначала попробуйте разрешить доступ только с сервера, который будет выполнять вызов вашего work.php с помощью .htaccess подобным образом:

 <FilesMatch "work.php$">
    Order deny,allow
    Deny from all
    Allow from 111.111.111.111
</FilesMatch>
  

где 111.111.111.111 — это IP сервера, который будет вызывать скрипт.

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

В примере.

Сервер, который вызывает скрипт:

 $hash = md5('my_secret_key'   date('dFYaG'));

// You can also use any other method you like to call the other script
// such us cURL, sockets and so on.
$f = fopen('http://www.myothersite.com/work.php?skr=' . $hash, 'r');
fclose($f);
  

и сервер, на котором размещен work.php

 $hash = md5('my_secret_key'   date('dFYaG'));

if($hash != $_GET['skr'])
{
    die('You do not have permission to access that file...');
}

// Rest of your code goes here
  

Комментарии:

1. Это выглядит хорошо и завершенно! Мне тоже нравится часть фильтрации ip.

2. Однако я не уверен насчет добавления части даты к ключу? Если дата-время, вычисленное вызывающей программой, отличается (например, на 1 секунду) от даты-времени, вычисленного на веб-сервере, не будут ли хэши больше не совпадать?

3. Приведенный выше вызов date возвращает дату, подобную «12November2011am2». ЕСЛИ мы предположим, что оба сервера расположены в одном часовом поясе, то результат будет абсолютно одинаковым, а также у вас будет разный ключ для каждого часа

Ответ №2:

В зависимости от способа доступа к нему, вы можете просто создать таблицу с зарегистрированными ключами API, использовать POST для встраивания данных в http-запрос и проверить, установлена ли переменная POST и соответствует ли она зарегистрированному ключу API.

В качестве альтернативы, у вас может быть пароль API, который перед сравнением преобразуется в ключ на стороне сервера для большей безопасности (если у кого-то есть прямой ключ API из базы данных и отправляет его в work.php после запуска, скажем, через хэш md5, он не будет оцениваться должным образом).

Ответ №3:

Вы могли бы немного упростить свою идею, просто придумав действительно длинный хэш и жестко закодировав его с обеих сторон. Рассматривайте это как ключ API для вашего сервиса (аналогичный тому, что вы могли бы получить от такого сервиса, как reCAPTCHA или Twilio, или что-то в этом роде).

Комментарии:

1. Привет, ты имеешь в виду, что каждый раз, когда предполагаемая программа вызывает php-файл, она вводит длинную (и всегда одну и ту же) жестко закодированную строку в качестве параметра (например.: ?hash=2JH3G5J3HFG6J26FKJ45K4G) и проверяет на стороне php, что параметр querystring был получен и имеет правильное значение? Если да, будет ли это считаться достаточно безопасным?

2. Да, примерно к этому я и веду. В RESTful API довольно часто используется аналогичная система, хотя обычно вы рассматриваете ее как пару открытый ключ / закрытый ключ. Но суть в том, что пока это достаточно сложно, это будет достаточно безопасно. У @Xleedos (одного из других ответчиков) есть более техническое объяснение того, что я имею в виду.

3. зачем использовать ключ API, когда веб-сервер может обрабатывать доступ?

4. Я сделал предложение, потому что это stackoverflow. Если бы я был на serverfault, я бы предложил другой подход.

Ответ №4:

Как насчет генерации пары ключей RSA? Затем зашифруйте секретную строку открытым ключом (с помощью вашего приложения) и сохраните закрытый ключ в безопасности в вашем PHP-скрипте. Если строка, переданная в PHP, может быть расшифрована с помощью закрытого ключа (и строка проверена), то это ваше приложение (если, конечно, ваше приложение не было взломано и открытый ключ не был извлечен).

Комментарии:

1. Это похоже на то, что я бы искал. Однако я не эксперт по криптографии, и мне немного трудно понять, какие части должны быть где (и это клиент-сервер, где должен быть объявлен и сохранен каждый ключ?)… не могли бы вы привести несколько примеров кода, которые могли бы применяться в моей ситуации?

2. Привет, извините за поздний ответ. У меня где-то есть немного PHP и .net-кода, в данный момент я на работе, поэтому опубликую его позже.