2010-04-05 81 views
5

我有一个PHP脚本来检查HTTP Referer。

if ($_SERVER['HTTP_REFERER'] == 'http://www.example.com/') {...} 

然而,这似乎inherintly不安全......因为如果用户进入'http://example.com/''http://www.ExaMple.com'(两者不匹配相等测试)时会发生什么。

问题:什么是更好的平等测试,以确保HTTP Referer来自'example.com'

+0

?它如何帮助? – 2010-04-05 19:49:48

+0

这只是第一道防线(特别是因为我知道引用者可以被欺骗)。它不保护任何安全,但同时,我不希望人们直接调用它来滥用我的web服务。这更多的意思是让人们保持半诚实。 – Hank 2010-04-05 19:53:30

+0

用户可以使用篡改数据来控制http_referer。但是,这个引用者不能被“伪造”用于CSRF攻击。 – rook 2010-04-05 20:18:16

回答

1

强制回复:HTTP_REFERER可能被欺骗,因此无法100%确定有人来自特定网站。

但是,如果您确实想依赖它,则可以使用正则表达式在HTTP_REFERER中查找“example.com”。 stristr()也可以工作,可能会被推荐,因为它会比正则表达式更快。它也区分大小写,因此将匹配“ExaMple.com”以及“example.com”。

+0

我知道,谢谢。但这不是问题。 – Hank 2010-04-05 19:42:56

+0

(这仍然是一个体面的第一道防线,但感谢提及它) – Hank 2010-04-05 19:43:22

+1

但不会* stristr *也匹配“notmyExample.com”这将是不受欢迎的? – Hank 2010-04-05 19:45:10

1

希望你不检查是否有任何显著。

你可以使用parse_url()函数来获取主机部分和检查,如果HTTP_REFERER包含实际的URL。
你也可以只SUBSTR WWW。从主机名。
字符大小写并不重要,因为它总是小写

或使用正则表达式。

0
if (strtolower($_SERVER['HTTP_REFERER']) == 'http://www.example.com/') {...} 

......怎么

$parts = explode('/',$_SERVER['HTTP_REFERER']); 
if (in_array('example.com',$parts) || in_array('www.example.com',$parts)) {...} 
+1

不确定这将始终有效,因为它假定1)结尾的斜线,2)“www。”而不是用户直接访问http://example.com – Hank 2010-04-05 19:50:21

+0

URL应始终进行规范化,即将辅助域重定向到主域(当使用多个域时)。 http://en.wikipedia.org/wiki/Canonicalization – jholster 2010-04-05 20:21:29

+0

@Hank - 再次检查我的答案... – 2010-04-05 20:49:20

3

parse_url()有位串杂耍的结合应该做你想要什么。试试这个:

$url = parse_url($_SERVER['HTTP_REFERER']); 
//take the last two 'dot segments' of the host 
$hostOnly = implode('.',array_slice(explode('.',$url['host']),-2)); 
if (strtolower($hostOnly) == 'example.com') { 
    //stuff 
} 

注意,parse_url()可能会失败形成严重的网址,所以你可能要添加一些错误检查是安全的。 HTTP_REFERER很容易被垃圾填满。

0

使用正则表达式,这会你使用它的防御成为

if(preg_match("%(http://)?(www\.)?example\.com(/)?%i",$_SERVER['HTTP_REFERER'])) { ... } 
相关问题