在PHP中确定引荐来源


102

确定当前页面发送(或通过AJAX调用)哪个页面的最可靠,最安全的方法是什么。$_SERVER['HTTP_REFERER']由于(缺乏)可靠性,我不想使用,并且我需要被调用的页面仅来自于源自我网站的请求。

编辑:我正在寻找从我的网站页面上调用执行一系列动作的脚本。


5
为什么说$ _SERVER ['HTTP_REFERER']不可靠?
米兰·巴布斯科夫

9
PHP实现是可靠的。问题在于,从来没有浏览器发送过此消息,并且您甚至可以根据需要对其进行修改。因此从客户的角度来看正确的说法并不可靠。
比里

2
一种可能的方法是将唯一键(例如GUID)放在页面的一个字段中,然后在下一个请求中将其发送回去。
披披,

找出服务器的IP地址并使用$_SERVER[REMOTE_ADDR]

Answers:


93

客户端浏览器发送的REFERER作为HTTP协议的一部分,因此确实不可靠。它可能不存在,可能是伪造的,如果出于安全原因,您就是无法信任它。

如果您想验证请求是否来自您的站点,那么您不能这样做,但是您可以验证用户是否已访问您的站点和/或已通过身份验证。Cookie是在AJAX请求中发送的,因此您可以依靠它。


5
如果要使用此方法,则仍应检查引荐来源网址,以防止CSRF en.wikipedia.org/wiki/Cross-site_request_forgery
JD Isaacks 2010年

17
理想情况下,您应该为每个用户的每个会话(如果是偏执狂,则为每个请求)使用唯一的令牌,以防止CSRF攻击。检查引荐来源仅仅是混淆的安全性,而不是真正的解决方案。
Seldaek 2010年

3
@Seldaek不,检查引荐来源是否不是“通过混淆确保安全”。尝试执行CSRF攻击的攻击者无法控制受害者浏览器发送的引荐来源网址,因此对其进行检查确实可以防御CSRF。但是,我会根据您的结论,建议您改用CSRF令牌,因为引荐检查方法有很多缺点,包括如果您的站点上有一个开放的重定向,将使您容易受到攻击,并且会破坏剥离引荐的用户代理。
马克·阿默里

@MarkAmery当然,这全都取决于您要防御的内容,但是总体上来说,使用客户端特定的HTTP标头并不是一个非常强大的安全模型。
塞尔达克2014年

23

我发现最好的是CSRF令牌,并将其保存在会话中,以用于需要验证引荐来源网址的链接。

因此,如果您正在生成FB回调,则它将类似于以下内容:

$token = uniqid(mt_rand(), TRUE);
$_SESSION['token'] = $token;
$url = "http://example.com/index.php?token={$token}";

然后index.php将如下所示:

if(empty($_GET['token']) || $_GET['token'] !== $_SESSION['token'])
{
    show_404();
} 

//Continue with the rest of code

我确实知道安全站点在所有安全页面上都做到了这一点。


1
以下是有关CSRF令牌的更多信息的链接:en.wikipedia.org/wiki/Cross-site_request_forgery
We0 2012年

7
你确定它是$_GET['token'] == $_SESSION['token']$_GET['token'] !== $_SESSION['token']
Timo Huovinen 2014年

17

使用$ _SERVER ['HTTP_REFERER']

将用户代理引至当前页面的页面地址(如果有的话)。这是由用户代理设置的。并非所有的用户代理都将设置此功能,有些用户代理提供了将HTTP_REFERER修改为功能的功能。简而言之,它不能真正被信任。

if (!empty($_SERVER['HTTP_REFERER'])) {
    header("Location: " . $_SERVER['HTTP_REFERER']);
} else {
    header("Location: index.php");
}
exit;

0

没有可靠的方法来检查这一点。告诉您它的确切来源完全在客户的掌握下。您可以想象使用仅在网站某些页面上放置的cookie或会话信息,但是这样做会破坏书签的用户体验。


0

阅读完所有假的引荐来源网址问题后,我们只剩下一个选项:即,我们希望作为引荐来源跟踪的页面应保留在会话中,并且以ajax调用,然后在会话中检查它是否具有引荐来源页面值并以其他方式进行操作否行动。

另一方面,当他请求任何其他页面时,则将引荐来源网址会话值设置为null。

请记住,会话变量仅在需求页面请求上设置。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.