使用HTTP_REFERER阻止用户访问站点的内部

我可以控制HttpServer,但不能控制ApplicationServer或Java应用程序,但我需要阻止直接访问这些应用程序上的某些页面。准确地说,我不希望用户自动访问发布直接GET / POST HTTP请求到相应servlet的表单。

所以,我决定根据 HTTP_REFERER 的值来阻止用户。毕竟,如果用户在网站内部进行导航,它将有一个合适的 HTTP_REFERER 。那是我的想法。

我在.htaccess文件中实现了一个重写规则:

RewriteEngine on 

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

我期望禁止访问未浏览网站的用户,但使用查询字符串向“servlet1”或“servlet2”servlet发出直接GET请求。但是我的期望突然结束,因为正则表达式(servlet1 | servlet2)/.+\?.+ 完全没有奏效。

当我将表达式更改为(servlet1 | servlet2)/.+ 时,我感到非常失望,并且它工作得很好,以至于我的用户无论是否浏览网站都被阻止。

所以,我的问题是:如果我没有访问权限/特权/时间来修改应用程序,我该如何完成这种不允许“机器人”直接访问某些页面的事情?

0
额外 编辑
意见: 3

9 答案

您无法通过其http请求分辨用户和恶意脚本。但是,您可以分析哪些用户在太短的时间内请求太多的页面,并阻止他们的IP地址。

0
额外

我没有解决方案,但我敢打赌,依靠推荐人将永远不会工作,因为用户代理可以根本不发送或欺骗它,让他们进入。

0
额外

如果您想阻止搜索引擎漫游器访问某些网页,请确保您使用格式正确的 robots.txt 文件。

使用HTTP_REFERER是不可靠的,因为它是很容易伪造

另一种选择是检查已知机器人的用户代理字符串(这可能需要修改代码)。

0
额外

Javascript是另一个有用的工具来防止(或至少延迟)屏幕抓取。大多数自动化的抓取工具没有Javascript解释器,所以你可以做一些事情,比如设置隐藏字段等。

编辑:根据 Phil Haack文章

0
额外

为了让事情更清楚些:

  1. 是的,我知道使用HTTP_REFERER是完全不可靠的,有点儿幼稚,但我很肯定那些从我学到的东西(从我这里学来的)可以使用Excel VBA实现自动化,但不知道如何颠覆HTTP_REFERER在最终的解决方案的时间跨度内。

  2. 我没有访问权限来修改应用程序代码。政治。你相信吗?所以,我必须等到权利持有者进行我所要求的更改。

  3. 根据以前的经验,我知道所需的更改需要两个月才能投入生产。不,把它们抛在脑后敏捷方法书头脑里的书没有任何改进。

  4. 这是一个内联网应用程序。所以我没有很多年轻人试图破坏我的声望。但我很年轻,试图破坏“来自印度的非常高档的全球咨询服务”的声望,但奇怪的是,在那里没有一个印度人在工作。

到目前为止,最好的答案来自“Michel de Mare”:根据他们的IP阻止用户。那么,我昨天做了。今天我想做一些更通用的事情,因为我有很多袋鼠用户(从IP地址跳到另一个地址),因为他们使用VPN或DHCP。

0
额外

我猜你试图阻止屏幕抓取?

我的老实说,通过检查HTTP_REFERER的价值只是一个坚持不懈的方法来解决和尝试解决这个问题非常困难。任何想要自动化提交的麻烦的人都会精明地将正确的引用者从他们的“自动机”中发送出去。

你可以尝试限速,但实际上并没有修改应用程序来迫使某种形式的人工验证(CAPTCHA),然后你会发现这很难防止。

0
额外

作为验证方法,使用引荐来源是非常不可靠的。正如其他人所说,它很容易被欺骗。您的最佳解决方案是修改应用程序(如果可以的话)

您可以使用CAPTCHA,或设置某种cookie或会话cookie,以跟踪用户上次访问的页面(会话很难欺骗)并跟踪页面查看历史记录,并且只允许浏览过该页面的用户进入您想要阻止的页面所需的页面。

这显然要求你有权访问有问题的应用程序,但它是最简单的方法(不完全,但在我看来,“足够好”)。

0
额外

您可能可以使用反CSRF令牌来实现您的目标。

This article explains it in more detail: Cross-Site Request Forgeries

0
额外

我不知道我是否可以一口气解决这个问题,但我们可以根据需要来回去解决。

首先,我想重复一下我认为你在说的话,并确保我很清楚。您想禁止向servlet1发送请求,并且servlet2请求没有正确的引用程序,并且 有查询字符串?我不确定我是否理解(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]

上面的所有错误referer请求都抓到了试图使用查询字符串提交数据的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]

希望这至少能让你更接近你的目标。请让我们知道它是如何工作的,我对你的问题感兴趣。

(顺便说一下,我同意引用阻止是安全性很差,但我也理解相互关系有时会迫使不完善和部分的解决方案,您似乎已经承认这一点。)

0
额外