在PHP中确定Referer

Unk*_*ech 101 php http-referer

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

编辑:我希望验证从我的网站上的页面调用预先形成一系列操作的脚本.

Sel*_*aek 91

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

如果您想验证某个请求是否来自您的网站,那么您不能,但您可以验证该用户是否已访问过您的网站和/或已通过身份验证.Cookie是在AJAX请求中发送的,因此您可以依赖它.

  • 理想情况下,每个用户每个会话应使用一个唯一的令牌(如果你是偏执的话,每个请求)以防止CSRF攻击.通过混淆检查引用者只是安全性,而不是一个真正的解决方案. (17认同)
  • 如果您想使用此方法,您仍应检查引荐来源以防止CSRF http://en.wikipedia.org/wiki/Cross-site_request_forgery (5认同)
  • @Seldaek不,检查引用者不是'通过混淆安全'.尝试执行CSRF攻击的攻击者无法控制受害者浏览器发送的引用者,因此检查*确实*防止CSRF.但是,我会坚持你的结论,你应该使用CSRF令牌,因为引用检查方法有[缺点](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet #Checking_The_Referer_Header)包括如果您的网站上有一个开放的重定向,并且破坏了剥离引用者的用户代理,则会使您容易受到攻击. (3认同)

We0*_*We0 23

我发现最好的是CSRF令牌,并将其保存在会话中,以便您需要验证引荐来源.

因此,如果您正在生成FB回调,那么它看起来像这样:

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

然后index.php将如下所示:

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

//Continue with the rest of code
Run Code Online (Sandbox Code Playgroud)

我知道安全网站可以为所有安全页面提供相同的功能.

  • 你确定它是`$ _GET ['token'] == $ _SESSION ['token']`而不是`$ _GET ['token']!== $ _SESSION ['token']`? (7认同)

AMB*_*AMB 17

使用$ _SERVER ['HTTP_REFERER']

将用户代理引用到当前页面的页面地址(如果有).这是由用户代理设置的.并非所有用户代理都会设置此功能,有些用户可以将HTTP_REFERER修改为功能.简而言之,它无法真正被信任.

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