Как проверить ссылающийся сервер. ($_SERVER[HTTP_REFERER])

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

Пользователь попадает на наш сайт по ссылке, которая выглядит примерно так:

siteB.com/certificate.php?companyid=1234&serverid=4321

Процесс упростился:

  • Пользователь находится на сайте А
  • Пользователь щелкает ссылку, ведущую на мой сайт (сайт B), чтобы просмотреть сертификат сайта A.
  • Мой сайт, сайт B должен подтвердить, что это действительно сайт A, который пытается отобразить сертификат, полученный сайтом A.

Первоначально я думал, что переменная $_SERVER может иметь значение, указывающее, кто является ссылающимся сервером, но ответы, которые я получил на публикацию вопроса об этом, показали, что, хотя эта информация хранится в $_SERVER["HTTP_REFERER"], она не ненадежен (плагины или пользователь могут изменить это значение).

Поскольку я не могу полагаться на это, мне нужен другой способ проверить, что ссылающийся сервер является тем, за кого он себя выдает. Я рассматривал возможность использования одноразового токена, но тогда действующий сервер мог бы просто распространять токены на другие серверы, принадлежащие клиенту (которые не были протестированы), и таким образом клиент мог заявить, что любое количество его серверов сертифицировано. нами всего за цену одного теста (а также нарушение целостности сертификата).

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

Моя идея до сих пор такова (и это ужасно):


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

Сценарий на сайте B с открытым потоком для пользовательской программы NaCl будет использовать curl чтобы получить IP-адрес(а) сервера(ов) сайта А и проверить.


Для меня это ужасно грубое решение (если это вообще решение), и хотя большинству пользователей не нужно смотреть на чей-то сертификат, заставляя пользователей, которым это небезразлично, проходить через обручи (установка и запуск программы NaCl) просто смотреть на сертификат просто безумие.

Это кажется немного глупым вопросом, но будет ли запуск этого как флэш-памяти таким же безопасным / небезопасным, как запуск программы NaCl?

Конечно, есть лучший способ сделать все это...


person Brad T.    schedule 05.03.2013    source источник


Ответы (2)


Лучше всего либо доверять REFERER, либо использовать заголовок ORIGIN (вам потребуется настроить сценарий AJAX, который можно добавить на сайты для использования ORIGIN).

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

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

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

То, что нужно запомнить:

  • AJAX позволяет изменять заголовки клиентом и/или сервером, за исключением заголовка ORIGIN, который гарантируется современными браузерами (но может быть изменен клиентом< /em> немного поработав)
  • Любой стандартный URL-запрос имеет все заголовки, сгенерированные браузером, поэтому им можно доверять (может быть изменен только клиентом).
  • Любой код или секрет (даже если он скомпилирован, запутан и т. д.), отправляемый на клиентские компьютеры, следует считать общедоступным.
  • Любой запрос, который не от браузера, может быть подделан во всех отношениях, кроме IP-адреса (и даже он может быть проксирован)
person Dave    schedule 05.03.2013
comment
Чудесно! Я не знал о заголовке ORIGIN. Простое использование ajax для проверки и перенаправления на URL-адрес страницы сертификата с одноразовым токеном (предоставленным в ответе на проверку) в строке запроса звучит идеально. Как вы сказали, у клиента нет причин менять это значение заголовка. Спасибо, Дэйв! - person Brad T.; 05.03.2013
comment
Прохладный!!! Если вам нужна помощь в программировании, дайте мне знать. Я хотел бы сделать это! ха-ха - person Phillip Berger; 05.03.2013

Моя идея... если возможно, заставить сервер, выдающий сертификат, создать файл cookie с hash на основе имени этого ссылающегося сервера и salt на основе другого набора критериев, который генерируется динамическим, но предсказуемым образом, например, с использованием пользовательского IP-адрес плюс день недели и, возможно, добавить число часов или текущую минуту (слишком короткий период в критериях приведет к НЕКОТОРЫМ ложноположительным ошибкам аутентификации, поэтому будьте осторожны). Затем, когда пользователь зайдет на ваш сайт, прочитайте хэш файла cookie и сравните его с хэшем, созданным на основе $_SERVER[“HTTP_REFERER”] и заранее установленных критериев. Недостатком этого является то, что ссылающиеся серверы могут опубликовать безопасный алгоритм, если они хотят быть мудаками.

Другой возможный более безопасный вариант — создать приложение JavaScript, которое вы передаете ссылающимся серверам, которое отправляет вашему серверу вызов AJAX, а ваш сервер, в свою очередь, возвращает хэш на основе тех же критериев, которые я упоминал выше. Затем файл cookie устанавливается направляющим сервером на основе вашего AJAX возвращаемого хэша, и когда они приходят на ваш сайт, он проверяется так же, как я упоминал ранее. Но так как вся обработка происходила на вашем сервере, это абсолютно безопасно. Звучит как крутой проект, удачи ему.

person Phillip Berger    schedule 05.03.2013
comment
Это не сработает. Предположим, что пользователь посещает поддельный сайт, сервер поддельного сайта отправляет запрос непосредственно на сервер хорошего сайта (CURL или что-то еще), извлекает информацию о файлах cookie и пересылает ее клиенту вместе с вредоносным содержимым. У поддельного сайта теперь есть хороший файл cookie, и любое шифрование/хэширование, которое вы использовали, является спорным. - person Dave; 05.03.2013
comment
Кроме того, идея AJAX (и помните, что единственным безопасным заголовком AJAX является ORIGIN) не более безопасна, чем использование заголовка REFERER в стандартном URL-адресе. Однако он может быть более устойчивым к прокси и другим вещам, которые могут пытаться скрыть рефереры (заставляет работать в большем количестве случаев, не делает его более или менее безопасным). - person Dave; 05.03.2013