Клиенты, которые приходят с ‘domain1.com?secretkey’, должны иметь доступ к ‘domain2.com’.
Домены находятся на разных серверах с разным веб-пространством и базой данных.
Я нашел 3 способа ограничения веб-страниц здесь:
wmtips.com/php/simple-ways-restrict-access-webpages-using.htm
Я не могу использовать аутентификацию, используя имя пользователя и пароль, поэтому я должен использовать Токен-URL-параметров и такая функция:
//This function returns True if query string contains secretkey and secretvalue.
//Otherwise it returns False
function CheckAccess()
{
return $_GET['secretkey']=='secretvalue';
}
Но как создать индивидуальный секретный ключ?
Если бы я использовал жестко закодированный токен в скрытом поле, я бы знал, что делать, но как использовать более безопасный секретный ключ?
Каковы распространенные криптографические способы отправки токена с помощью URL-параметра?
Так что я думаю, что я должен использовать Токен-URL-параметров
Это разумный (если несовершенный) вариант. Вы должны иметь секретный общий доступ между двумя доменами, который не передается браузеру.
Это может быть сделано через базу данных, с двумя методами жизнеспособной паранойи.
domain1.com
устанавливает секретный ключ (см. ниже), и это значение сохраняется в базе данных вместе с критериями аутентификации, такими как IP-адрес, дата и время, хэш идентификации браузера ($_SERVER['HTTP_USER_AGENT']
), и все, что вы хотите использовать, чтобы быть более избирательным при проверке секретного ключа, — это не просто счастливая случайность.
В идеале база данных должна находиться на том же сервере, что и домен (ы), и доступ к ней должен осуществляться только локально. Но это скользящая шкала того, насколько вы действительно хотите быть в безопасности и сколько времени / денег / ресурсов вы хотите инвестировать в эту тему.
Этот секретный ключ передается domain2.com
через ваш (urlencode
г) ПОЛУЧИТЬ параметр, как вы иллюстрируете.
base64_
не требуется, но если вы хотите использовать его, нет никакого вреда. Лучше (обязательно) использовать urlencode($variable)
при установке секретного ключа в URL ссылки.
ПРИМЕЧАНИЕ: вам не нужно использовать urldecode()
на полученных $_GET
переменная.
Секретный ключ не должен содержать какой-либо из указанных выше идентифицируемой информации и быть чисто случайным. Это должно быть долго. Другой ответ здесь цитирует 8 символов. Это будет сломано почти мгновенно. Вы хотите создать ключевую строку как можно дольше. Вы можете быть ограничены только системой индексации на VARCHAR
столбец базы данных, где хранится тот же секретный ключ. поэтому вы хотите ключ из 184 символов, когда полностью декодированы.
использование random_bytes()
или же openssl_random_pseudo_bytes()
, в зависимости от вашей версии PHP.
запустите это в цикле, чтобы сделать длину ключа, и, используя примеры из страниц руководства выше, установите буквенно-цифровую строку, используя bin2hex
или похожие.
(»Почему нет, Шерлок?«)
Когда у вас есть секретный ключ, вам нужно проверить, находится ли он в базе данных. Самый простой способ — построить базу данных так, чтобы столбец секретного ключа был UNIQUE INDEX
(MySQL) и так, если есть повторение, это не будет вставить. Вы должны построить логику, чтобы, если ключ не вставлен, вам пришлось перезапустить и создать новый ключ.
При сохранении ключа в базе данных вы должны также сохранить другие метаданные, как указано выше, IP-адреса, хеши браузера, дату и т. Д.
После завершения этого процесса вы можете перейти к проверке действительного URL-адреса.
У вас есть ключ в вашем $_GET
Значение PHP. Передайте этот ключ в свою базу данных (конечно, используя подготовленные заявления) и проверьте, что он существует.
Как только вы обнаружите, что он существует, вы можете проверить метаданные и подтвердить, что они верны. Например, время вызова запроса составляет не более x количества минут после значения datetime в базе данных для создания строки.
Какие несоответствия вы проверяете и на которые реагируете, зависит только от вас, но в качестве примера стоит проверить, что хеш браузера такой же, так что вы можете быть уверены, что один браузер использовал для доступа к domain1.com
тот же браузер, что и доступ domain2.com
,
Итак, браузер запрашивает строку, которая не существует? Взрыв 5 секунд sleep()
заявление об этом условии, прежде чем выкинуть на домашнюю страницу. Браузер запрашивает историческую строку (старое значение даты и времени) sleep(5)
на это, прежде чем выкинуть на домашнюю страницу. и т. д.
Если вы хотите, вы можете записать IP-адреса неудачных попыток и использовать это для подсчета (в другой таблице базы данных) любых IP-блоков, которые неоднократно пытаются взломать ваши хэши, тогда вы можете использовать больше кода, чтобы добавить штраф времени, например, если 205.453.345.xxx
IP-адреса имеют 25 неудачных попыток, вы можете добавить дополнительные sleep()
для любого доступа с этого IP-адреса или даже для более высоких номеров просто отключите этот IP-блок, даже не потрудившись проверить хеш.
Не сообщайте пользователю / браузеру причину сбоя какого-либо конкретного хеш-токена. Злоумышленник, использующий зондирование, может использовать эти данные, чтобы узнать больше о вашем процессе проверки хеша или метаданных.
Будьте предельно осторожны с блокировкой или чрезмерной приостановкой IP-адресов, поскольку тот, кто использует IP-адреса, постоянно меняется. Если вы ведете подсчет сбоев IP по блокам [123.456.678.xxx]
или на основе адреса вы не должны хранить счета дольше, чем, скажем, 7 дней. в противном случае IP-адреса, которые исторически принадлежали хакерам месяц назад, будут принадлежать подлинным пользователям, которые по-прежнему несут штрафы, но не по своей вине.
Хранение сбоев IP для каждого адреса обходится дорого в дисковом пространстве и относительно бесполезно. Отслеживание блоков более эффективно.
После того, как вы проверили секретный ключ, и метаданные достаточно последовательны, и вы довольны им, установите cookie / сеанс на domain2.com
разрешить этому браузеру доступ, а затем удалить хеш-ключ из базы данных, сохранив его уникальную возможность доступа.
Все отмеченное выше может сделать лучшее из несовершенной ситуации. комментарий от KIKO Software следует учитывать:
Вы не можете создать безопасную систему, предоставив только параметр URL, см. «URL https с параметром токена, насколько это безопасно?«Я знаю, что это не совсем то, что вы делаете, но идея та же. Эта проблема может быть решена, но она требует много объяснений и предостережений.
В этой конкретной теме гораздо больше, чем описано в этом ответе, но это требует самоотверженности, чтения и обучения. Ты сможешь НИКОГДА иметь совершенно защищенную систему (это все равно, что пытаться поймать облако), поэтому вам нужно подумать о том, каковы ваши риски, насколько они важны и какое время и усилия стоит найти для снижения рисков.
Большая часть безопасности заключается не в решении проблем, а в смягчении их последствий. В приведенном выше примере может быть возможно скомпрометировать определенный секретный ключ, но вероятность этого — составление ключа в разрешенном временном окне и с помощью эквивалентно эквивалентного браузера и использование того же IP-адреса — очень маленький, но абсолютно не невозможно.
Не рекомендуется. Шифрование требует большой вычислительной мощности и аналогично описанному выше, но имеет гораздо большее окно атаки.
Единственная причина, по которой я вижу использование шифрования, — это если по какой-то глупой причине вы не можете использовать базу данных. Поэтому вы можете создать зашифрованный текст метаданных (IP, дату, время и т. Д.), А затем отправить их на domain2.com
для PHP на domain2.com для проверки сравнения зашифрованного текста.
Скажем, например, метаданные, которые вы обычно помещаете:
$plainText = $_SERVER['REMOTE_ADDR'].date("Y-m-d").md5($_SERVER['HTTP_USER_AGENT']);
$options = [ 'cost' => 12,];
$cypher = password_hash($plainText, PASSWORD_BCRYPT, $option );
$urlCypher = urlencode($cypher);
И читать это на domain2.com
вы бы использовали:
$checker = $_SERVER['REMOTE_ADDR'].date("Y-m-d").md5($_SERVER['HTTP_USER_AGENT']);
if(password_verify($checker,$_GET['keystring'])){
//values compare ok.
}
Хотя это работает, оно также может работать для любого удаленного компьютера, который вводит правильные данные шифра, потому что все части проверенных данных уже известны браузеру конечного пользователя.
Нет независимого наблюдателя, в отличие от сценария базы данных.
Этот метод не рекомендуется, так как он сильно загружает процессор и потенциально более уязвим
Некоторые ссылки на источники:
Других решений пока нет …