Заблокируйте доступ пользователей к внутренним компонентам сайта с помощью HTTP_REFERER

У меня есть контроль над 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", используя строки запроса. Но мои ожидания внезапно закончились, потому что регулярное выражение (servlet1|servlet2)/.+\?.+ вообще не работало.

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

Итак, мой вопрос: как я могу сделать это, не позволяя «роботам» иметь прямой доступ к определенным страницам, если у меня нет доступа / привилегий / времени для изменения приложения?

SQL Injection: Атаки в реальной жизни и как это вредит бизнесу
SQL Injection: Атаки в реальной жизни и как это вредит бизнесу
Один-единственный вредоносный запрос может нанести ущерб вашему бизнесу. Уязвимости вашего кода могут привести к:
5
0
2 088
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

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

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

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

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

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

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

Обновлено: что-то вроде эта статья Фила Хаака.

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

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

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

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

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

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

Чтобы прояснить ситуацию:

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

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

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

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

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

Ответ принят как подходящий

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

Во-первых, я хочу повторить то, что, как мне кажется, вы говорите, и убедиться, что я понятен. Вы хотите запретить запросы к сервлету 1 и сервлету 2, если у запроса нет правильного реферера, а в делает есть строка запроса? Я не уверен, что понимаю (servlet1 | servlet2) /.+\?.+, потому что похоже, что вам нужен файл под servlet1 и 2. Я думаю, что, возможно, вы комбинируете PATH_INFO (перед "?") С GET строка запроса (после "?"). Похоже, что часть PATH_INFO будет работать, но тест запроса GET - нет. Я провел быстрый тест на своем сервере, используя 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]

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

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

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

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

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