使用php伪造referer的方法 利用referer防止图片盗链
什么是HTTP Referer简言之,HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。比如从我主页上链接到一个朋友那里,他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。Referer其实应该是英文单词Referrer,不过拼错的人太多了,所以编写标准的人也就将错就错了。 我的问题 我刚刚把feed阅读器改变为Gregarius,但他不像我以前用的liferea,访问新浪博客的时候,无法显示其中的图片,提示“此图片仅限于新浪博客用户交流与沟通”,我知道,这就是HTTP Referer导致的。 由于我上网客户端配置的特殊性,首先怀疑是squid的问题,但通过实验排除了,不过同时发现了一个Squid和Tor、Privoxy协同使用的隐私泄露问题,留待以后研究。 Gregarius能处理这个问题么? 答案是否定的,因为Gregarius只是负责输出html代码,而对图像的访问是有客户端浏览器向服务器请求的。 不过,安装个firefox扩展也许能解决问题,文中推荐的”Send Referrer”我没有找到,但发现另外一个可用的:”RefControl“,可以根据访问网站的不同,控制使用不同的Referer。 但是我不喜欢用Firefox扩展来解决问题,因为我觉得他效率太低,所以我用更好的方式——Privoxy。 Privoxy真棒 在Privoxy的default.action中添加两行: {+hide-referrer{forge}} .album.sina.com.cn 这样Gregarius中新浪博客的图片就出来了吧?+hide-referrer是Privoxy的一个过滤器,设置访问时对HTTP Referer的处理方式,后面的forge代表用访问地址当作Refere的,还可以换成block,代表取消Referer,或者直接把需要用的Referer网址写在这里。 用Privoxy比用Firefox简单的多,赶紧换吧。 From https to http 我还发现,从一个https页面上的链接访问到一个非加密的http页面的时候,在http页面上是检查不到HTTP Referer的,比如当我点击自己的https页面下面的w3c xhtml验证图标(网址为http://validator.w3.org/check?uri=referer),从来都无法完成校验,提示: No Referer header found! 原来,在http协议的rfc文档中有定义: 代码如下: 15.1.3 Encoding Sensitive Information in URI's
Clients SHOULD NOT include a Referer header field in a (non-secure) 这样是出于安全的考虑,访问非加密页时,如果来源是加密页,客户端不发送Referer,IE一直都是这样实现的,Firefox浏览器也不例外。但这并不影响从加密页到加密页的访问。 利用Referer防止图片盗链虽然Referer并不可靠,但用来防止图片盗链还是足够的,毕竟不是每个人都会修改客户端的配置。实现一般都是通过apache的配置文件,首先设置允许访问的地址,标记下来: # 只允许来自don.com的访问,图片可能就放置在don.com网站的页面上 SetEnvIfNoCase Referer "^http://www.don.com/" local_ref # 直接通过地址访问 SetEnvIf Referer "^$" local_ref 然后再规定被标记了的访问才被允许: 代码如下: Allow from env=local_ref 或者 代码如下: Order Deny,Allow Deny from all Allow from env=local_ref 不要使用Rerferer的地方不要把Rerferer用在身份验证或者其他非常重要的检查上,因为Rerferer非常容易在客户端被改变,不管是通过上面介绍的Firefox扩展,或者是Privoxy,甚至是libcurl的调用,所以Rerferer数据非常之不可信。 如果你想限制用户必须从某个入口页面访问的话,与其使用Referer,不如使用session,在入口页面写入session,然后在其他页面检查,如果用户没有访问过入口页面,那么对应的session就不存在,参见这里的讨论。不过和上面说的一样,也不要过于相信这种方式的“验证”结果。 个人感觉现在Rerferer除了用在防盗链,其他用途最多的就是访问统计,比如统计用户都是从哪里的链接访问过来的等等。 HTTP-REFERER这个变量已经越来越不可靠了,完全就是可以伪造出来的东东。 PHP(前提是装了curl): 代码如下: $ch = curl_init();
curl_setopt ($ch,CURLOPT_URL,"http://www.d.cn/xxx.asp"); curl_setopt ($ch,CURLOPT_REFERER,"http://www.d.cn/"); curl_exec ($ch); curl_close ($ch);PHP(不装curl用sock) $server = 'www.dc9.cn'; $host = 'www.dc9.cn'; $target = '/xxx.asp'; $referer = 'http://www.d.cn/'; // Referer $port = 80; $fp = fsockopen($server,$port,$errno,$errstr,30); if (!$fp) { echo "$errstr ($errno) n"; } else { $out = "GET $target HTTP/1.1rn"; $out .= "Host: $hostrn"; $out .= "Cookie: ASPSESSIONIDSQTBQSDA=DFCAPKLBBFICDAFMHNKIGKEGrn"; $out .= "Referer: $refererrn"; $out .= "Connection: Closernrn"; fwrite($fp,$out); while (!feof($fp)) { echo fgets($fp,128); } fclose($fp); } javascript JS不支持^_^原理都是sock构造http头来senddata。其他语言什么的比如perl也可以, (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |