0x00 前言

最近用Python非常多,确实感受到了Python的强大与便利。但同时我并没有相见恨晚的感觉,相反我很庆幸自己没有太早接触到Python,而是基本按着CC++JavaPython这条路学习下来的,因为过早使用太便利的方法有可能使你对底层细节一无所知。

现在我对HTTP协议的了解完全要归功于当初用Java写爬虫时遇到的各种问题,如果我很早就开始使用Pythonurllib2或者requests,那么我现在对HTTP协议的认识可能依然非常肤浅。

好了,如果你对HTTP协议不太熟悉的话,强烈建议你先去看看相关知识,也可以看看《图解HTTP》,会有一个更全面的了解。

0x01 Referer简介

简单来说,Referer是HTTP协议中的一个请求报头,用于告知服务器用户的来源页面。比如说你从Google搜索结果中点击进入了某个页面, 那么该次HTTP请求中的Referer就是Google搜索结果页面的地址。如果你的某篇博客中引用了其他地方的一张图片,那么对该图片的HTTP请求 中的Referer就是你那篇博客的地址。

一般Referer主要用于统计,像CNZZ、百度统计等可以通过Referer统计访问流量的来源和搜索的关键词(包含在URL中)等等,方便站长们有针性对的进行推广和SEO什么的~

当然Referer另一个用处就是防盗链了,主要是图片和网盘服务器使用的较多。盗链的危害不言而喻,侵犯了版权不说,增加了服务器的负荷,却没有给真正的服务提供者带来实际利益(广告点击什么的)

另外要注意的是,Referer是由浏览器自动为我们加上的,以下情况是不带Referer的

  • 直接输入网址或通过浏览器书签访问
  • 使用JavaScriptLocation.href或者是Location.replace()
  • HTTPS等加密协议

当然你可以通过在Chrome或者Firefox浏览器中安装一些插件去除Referer甚至进行Referer欺骗。如果是自己写爬虫的话,Referer是完全受我们掌控的,想怎么改就怎么改~

0x02 Referer的安全问题

严格来说Referer并非一些安全问题的根源,只不过充当了一个帮凶。咱们以新浪微博曾经的一个漏洞(新浪微博gsid劫持)为例说明吧~

什么是gsid呢?

gsid是一些网站移动版的认证方式,移动互联网之前较老的手机浏览器不支持cookie,为了能够识别用户身份(实现类似cookie的作 用),就在用户的请求中加入了一个类似“sessionid”的字符串,通过GET方式传递,带有这个id的请求,就代表你的帐号发起的操作。后来又因用 户多次认证体验不好,gsid的失效期是很长甚至永久有效的(即使改了密码也无用哦,这个问题在很多成熟的web产品上仍在发生)。也就是说,一旦攻击者 获取到了这个gsid,就等同于长期拥有了你的身份权限,对你的帐号做任意操作。

相信看到这里你已经能猜到这个漏洞的基本原理了,gsid这个非常重要的参数竟然就在URL里,只要攻击者在微博上给你发一个链接(指向攻击者的服 务器),你通过手机点击进入之后,手机当前页面的URL就通过Referer主动送到了攻击者的服务器上,攻击者自然就可以轻松拿到你的gsid进而控制 你的账号。

当然防范这种攻击的方法很多,了解更多请戳新浪微博gsid劫持

0x03 反反盗链

反盗链的方法这里就不多说了,网上一搜一箩筐,不同平台有不同的实现方法。

加入反盗链机制后,从其他非服务提供者指定的来源的HTTP请求就得不到正常结果了,比如百度的反盗链机制~

注意,上面的不是截图,就是盗链,你可以用审查元素进行查看。

当然,访问用户可以通过给浏览器安装一些插件去除Referer来正常显示,但是并非每一个用户都那么爱折腾。有没有一个简单粗暴跨平台跨浏览器的服务器端解决方案呢?也就是说访问用户什么都不用做就可以正常显示。

当然有,看下面这张图片,你同样可以用审查元素进行查看(这里为了防止缓存我使用的是不一样的图片)

同样是百度域名下面的图片,为什么一张可以正常显示,另一张就显示盗链呢?我们来抓包看看

显示盗链的图片

正常显示的图片

看到了吗?正常显示的那张图片的HTTP请求中没有Referer,所以我们得到了正常的结果

那么问题来了——Referer是怎么去除的呢?

这里我用到了referrer-killer,里面还有一个Demo,具体用法可以查看本篇博客的网页源码,或者那个Demo的网页源码。其实就几行代码~

<script src="/assets/js/ReferrerKiller.js"></script>

<span id="noreferer"></span>

<script>
document.getElementById('noreferer').innerHTML = ReferrerKiller.imageHtml('http://a.hiphotos.baidu.com/ting/pic/item/3bf33a87e950352aa210e8635043fbf2b2118b6c.jpg');
</script>

粗看referrer-killer的原理并不复杂,动态生成了一个iframe,并在这个iframe里面加入img标签来进行显示。

等等,如果仅仅是这样的话Referer依然会存在,要么是iframe父页面的地址,要么是iframe属性中src的地址,详情请戳What is the HTTP Referer if the link is clicked in an <iframe>?,里面有详细解释。

再仔细看代码,发现iframe中src的值为javascript:"<!doctype html>......",原来是把iframe中的HTML代码全部放到了src中,使用这种方法就可以去掉Referer。其实乌云早有大神给出了方法,只不过没有工具化罢了,详情请戳json hijack如何丢掉referer,注意看@Sogili@gainover同学的回复。

0x04 总结

本篇博客中的Referer和上一篇博客中涉及到的User-Agent都与HTTP协议有关。当遇到一些与底层协议相关的问题时,如果对其不了解,往往只能束手无策或者要浪费很多时间。

因此,即便Python提供了非常强大的功能,花时间去了解HTTP协议依然是十分必要的。

Referer反反盗链的更多相关文章

  1. 通过设置Referer反"反盗链"

    package cn.searchphoto.util; import java.io.File; import java.io.FileOutputStream; import java.io.In ...

  2. 对付"反盗链"

    对付"反盗链" 某些站点有所谓的反盗链设置,其实说穿了很简单, 就是检查你发送请求的header里面,referer站点是不是他自己, 所以我们只需要像把headers的refer ...

  3. sevlet实现反盗链

    有时候为了网站的版权和安全问题,我们需要为我们的网站应用设置防盗链,这样可以保证我们网站的一些资源的安全性.防盗链的主要是通过获取http的请求头referer的信息来和我们的网站地址做对比,如果相同 ...

  4. 跳过图片反盗链js

    页面增加<iframe> <iframe id="ifa" style="display:none" /> 原来html: <im ...

  5. 关于python 爬虫遇到的反盗链

    首先声明:目标网址是从别人案例里得到的,内容你懂的... 本来闲来无事,学习下爬虫的知识,遇到恶心的反盗链,好在目标网址防盗链简单,代码里注明了如何去查看目标网址的防盗检查: 防盗链原理 http标准 ...

  6. 利用Referer请求头阻止"盗链"

    转自:http://wisdomsong2007.blog.163.com/blog/static/47783725200882523820664/ 前言 有一些站点自己没有提供下载空间,但是为了吸引 ...

  7. python爬虫---详解爬虫分类,HTTP和HTTPS的区别,证书加密,反爬机制和反反爬策略,requests模块的使用,常见的问题

    python爬虫---详解爬虫分类,HTTP和HTTPS的区别,证书加密,反爬机制和反反爬策略,requests模块的使用,常见的问题 一丶爬虫概述       通过编写程序'模拟浏览器'上网,然后通 ...

  8. scrapy反反爬虫

    反反爬虫相关机制 Some websites implement certain measures to prevent bots from crawling them, with varying d ...

  9. scrapy反反爬虫策略和settings配置解析

    反反爬虫相关机制 Some websites implement certain measures to prevent bots from crawling them, with varying d ...

随机推荐

  1. C-最长回文子串(1)

    最长回文子串,就是在字符串中找到最长的对称的子串. s是一个字符串. int max = 0; for(i = 0;i<m;i++) for(j = i;j<m;j++) if(s[i.. ...

  2. SFTP上传下载(C#)

    sftp是ftp协议的升级版本,是牺牲上传速度为代价,换取安全性能,本人开始尝试使用Tamir.SharpSSH.dll但它对新版本的openssh 不支持,所有采用Ssh.Net方式 需要依赖:Re ...

  3. cocos2d-x游戏开发系列教程-中国象棋05-开始游戏

    前情回顾 通过CCMainMenu的init函数,已经把所有的按钮,棋子都摆放完毕了,但是这个时候,棋子是不能走动的,只有在开始游戏之后才能移动棋子. 点击

  4. 教程:查找内存泄漏 (JavaScript)

    本主题带领您完成使用 JavaScript 内存分析器确定并修复简单内存问题的过程.在本教程中,我们创建一个生成大量数据的应用程序.我们预期在导航到新页时该应用程序会释放数据.  说明 JavaScr ...

  5. Swift学习笔记十三:继承

    一个类能够继承(inherit)还有一个类的方法(methods),属性(property)和其他特性 一.基本的语法 class Human{ var name :String init(){ na ...

  6. CSS:重量和级联规则,确定其优先级

    资源:http://www.ido321.com/1063.html 首先,给大家看一篇关于CSS优先级的演示样例:http://www.ido321.com/76.html 一.主要的优先级规则 比 ...

  7. 搭建python集成开发环境.

    需要搭建的内容一共有三项, python ,wxpython 以及spe.     其中spe 是python 的可视化集成开发环境(ide) , 其需要python GUI图形库wxpython的支 ...

  8. Android程序检测网络是否可用

    在做Android应用程序中,连接网络的时候,常常要用到检测网络状态是否可用,在这里分享一个比较好用的方法. 本人参考:http://blog.csdn.net/sunboy_2050/article ...

  9. AssertValid函数学�

    转自http://tsitao.blog.163.com/blog/static/29795822006914105840496/ VC的调试中,AssertValid和Dump函数的应用 CObje ...

  10. Android中View绘制优化二一---- 使用<include />标签复用布局文件

    本文原创, 转载请注明出处:http://blog.csdn.net/qinjuning   译二:   使用<include />标签复用布局文件      翻译地址:http://de ...