#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-кода, в данный момент я на работе, поэтому опубликую его позже.