Блокировать доступ пользователя к внутренним функциям сайта с помощью HTTP_REFERER

StackOverflow https://stackoverflow.com/questions/3486

Вопрос

У меня есть контроль над HTTPServer, но не над ApplicationServer или Java-приложениями, находящимися там, но мне нужно заблокировать прямой доступ к определенным страницам в этих приложениях.Точнее, я не хочу, чтобы пользователи автоматизировали доступ к формам, отправляя прямые HTTP-запросы GET / POST соответствующему сервлету.

Итак, я решил блокировать пользователей, основываясь на значении HTTP_REFERER.В конце концов, если пользователь осуществляет навигацию внутри сайта, у него будет соответствующий HTTP_REFERER.Что ж, именно так я и думал.

Я внедрил правило перезаписи в файл .htaccess, в котором говорится:

RewriteEngine on 

# Options +FollowSymlinks
RewriteCond %{HTTP_REFERER} !^http://mywebaddress(.cl)?/.* [NC]
RewriteRule (servlet1|servlet2)/.+\?.+ - [F]

Я ожидал запретить доступ пользователям, которые не перемещались по сайту, но отправляли прямые запросы GET к сервлетам "servlet1" или "servlet2", используя querystrings.Но мои ожидания резко оборвались, потому что регулярное выражение (servlet1|servlet2)/.+\?.+ это вообще не сработало.

Я был действительно разочарован, когда сменил это выражение на (servlet1|servlet2)/.+ и это сработало так хорошо, что мои пользователи были заблокированы независимо от того, заходили они на сайт или нет.

Итак, мой вопрос заключается в следующем:Как я могу добиться этого, не разрешая "роботам" прямой доступ к определенным страницам, если у меня нет доступа / привилегий / времени для изменения приложения?

Это было полезно?

Решение

Я не уверен, смогу ли я решить это за один раз, но мы можем возвращаться туда и обратно по мере необходимости.

Во-первых, я хочу повторить то, что, по моему мнению, вы говорите, и убедиться, что я ясно выразился.Вы хотите запретить запросы к servlet1, а servlet2 - это запрос, у которого нет соответствующего референта, и он делает у вас есть строка запроса?Я не уверен, что понимаю (servlet1 | servlet2) /.+ \ ?.+ потому что похоже, что вам требуется файл в servlet1 и 2.Я думаю, может быть, вы объединяете PATH_INFO (перед "?") со строкой запроса GET (после "?").Похоже, что часть PATH_INFO будет работать, но тест GET query - нет.Я провел быстрый тест на своем сервере, используя script1.cgi и script2.cgi, и следующие правила сработали для выполнения того, о чем вы просите.Очевидно, они немного отредактированы, чтобы соответствовать моему окружению:

RewriteCond %{HTTP_REFERER} !^http://(www.)?example.(com|org) [NC]
RewriteCond %{QUERY_STRING} ^.+$
RewriteRule ^(script1|script2)\.cgi - [F]

Выше были зафиксированы все запросы с неправильной ссылкой на script1.cgi и script2.cgi, которые пытались отправить данные, используя строку запроса.Однако вы также можете отправлять данные с помощью path_info и путем публикации данных.Я использовал эту форму для защиты от использования любого из трех методов с неправильным реферером:

RewriteCond %{HTTP_REFERER} !^http://(www.)?example.(com|org) [NC]
RewriteCond %{QUERY_STRING} ^.+$ [OR]
RewriteCond %{REQUEST_METHOD} ^POST$ [OR]
RewriteCond %{PATH_INFO} ^.+$
RewriteRule ^(script1|script2)\.cgi - [F]

Основываясь на примере, который вы пытались заставить работать, я думаю, это то, что вы хотите:

RewriteCond %{HTTP_REFERER} !^http://mywebaddress(.cl)?/.* [NC]
RewriteCond %{QUERY_STRING} ^.+$ [OR]
RewriteCond %{REQUEST_METHOD} ^POST$ [OR]
RewriteCond %{PATH_INFO} ^.+$
RewriteRule (servlet1|servlet2)\b - [F]

Надеюсь, это, по крайней мере, приблизит вас к вашей цели.Пожалуйста, дайте нам знать, как это работает, мне интересна ваша проблема.

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

Другие советы

У меня нет решения, но я готов поспорить, что полагаться на реферера никогда не сработает, потому что агенты-пользователи могут вообще не отправлять его или подделать на что-то, что их впустит.

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

Использование реферера в качестве метода проверки очень ненадежно.Как уже упоминали другие люди, его легко подделать.Ваше лучшее решение - изменить приложение (если вы можете).

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

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

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

Редактировать:Что-то вроде эта статья Фила Хаака.

Я предполагаю, что вы пытаетесь предотвратить царапание экрана?

По моему честному мнению, это сложная задача, и попытка исправить ее, проверив значение HTTP_REFERER, - это просто липкий пластырь.Любой, кто потрудится автоматизировать отправку заявок, будет достаточно сообразителен, чтобы отправить правильного реферера из своего "автомата".

Вы могли бы попробовать ограничить скорость, но фактически не модифицируя приложение, чтобы в какой-то момент принудительно выполнить какую-то проверку is-this-a-human (КАПЧУ), тогда вам будет трудно это предотвратить.

Если вы пытаетесь запретить ботам из поисковых систем доступ к определенным страницам, убедитесь, что вы используете правильно отформатированный robots.txt файл.

Использование HTTP_REFERER ненадежно, потому что это легко подделать.

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

Чтобы все было немного более понятно:

  1. Да, я знаю, что использование HTTP_REFERER абсолютно ненадежно и несколько по-детски, но я почти уверен, что люди, которые научились (может быть, у меня?) автоматизировать работу с Excel VBA, не будут знать, как подорвать HTTP_REFERER в течение периода времени, необходимого для получения окончательного решения.

  2. У меня нет доступа / привилегий для изменения кода приложения.Политика.Ты в это веришь?Итак, я должен дождаться, пока правообладатель внесет изменения, которые я запросил.

  3. По предыдущему опыту я знаю, что для запуска запрошенных изменений в производство потребуется два месяца.Нет, вбрасывание им в головы Книг по Гибким методологиям ничего не улучшило.

  4. Это приложение для внутренней сети.Так что у меня не так много молодежи, пытающейся подорвать мой престиж.Но я достаточно молод, чтобы пытаться подорвать престиж "очень модной глобальной консалтинговой компании, которая поступает из Индии", но где, как ни странно, не работает ни один индиец.

Пока что лучший ответ дает "Мишель де Мар".:блокируйте пользователей на основе их IP-адресов.Ну, это я сделал вчера.Сегодня я хотел сделать что-то более общее, потому что у меня много пользователей kangaroo (переходящих с одного IP-адреса на другой), потому что они используют VPN или DHCP.

Возможно, вы сможете использовать токен защиты от CSRF для достижения того, что вам нужно.

В этой статье это объясняется более подробно: Подделки межсайтовых запросов

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top