аутентификация — как ограничить клиентам доступ к другим URL-адресам по случайному токену

Клиенты, которые приходят с ‘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-параметра?

0

Решение

Так что я думаю, что я должен использовать Токен-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.
}

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

Нет независимого наблюдателя, в отличие от сценария базы данных.

Этот метод не рекомендуется, так как он сильно загружает процессор и потенциально более уязвим


Некоторые ссылки на источники:

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]