允许空白referer防盗链图片的破解

最近【2019 年 4 月 24 日左右发现】微博图床出问题了,访问图片链接全部是返回 403 状态码,表示拒绝访问,其实是微博图床开启了防盗链,本文就记录这个现象以及可行的解决方案。

iframe方案

Javascript源码

function showImg( url ) {
    var imgid = Math.random(),
    frameid = 'frameimg' + imgid;
    window['img'+imgid] = '<img id="img" src=\''+url+'\' /> <script> window.onload = function() { parent.document.getElementById(\''+frameid+'\').height = document.getElementById(\'img\').height+\'px\'; }<'+'/script>';
    document.write('<iframe id="'+frameid+'" src="javascript:parent[\'img'+imgid+'\'];" frameBorder="0" scrolling="no" width="100%"></iframe>');
}

调用方法

showImg('图片地址');

例子

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
<script type="text/javascript">  
function showImg( url ) {
    var imgid = Math.random(),
    frameid = 'frameimg' + imgid;
    window['img'+imgid] = '<img id="img" src=\''+url+'\' /> <script> window.onload = function() { parent.document.getElementById(\''+frameid+'\').height = document.getElementById(\'img\').height+\'px\'; }<'+'/script>';
    document.write('<iframe id="'+frameid+'" src="javascript:parent[\'img'+imgid+'\'];" frameBorder="0" scrolling="no" width="100%"></iframe>');
}
</script>


 <h1>直接盗链:</h1><br>  
 <img src="http://ww4.sinaimg.cn/bmiddle/9150e4e5gy1fpv6cc83cnj20c80iagmd.jpg" /><br>  
 <h1>js破解盗链:</h1><br>  

 <div id="hotlinking">

 <script type="text/javascript">
 showImg('http://ww4.sinaimg.cn/bmiddle/9150e4e5gy1fpv6cc83cnj20c80iagmd.jpg');
 </script>

 </div>

兼容性

已测试IE6、IE7、IE8、chrome 7、FF3.6、Opera10.63

给img标签添加Referrer-Policy属性

给你页面中的img添加参数

<img src="" referrerPolicy="no-referrer">

缺点

目前 微软系浏览器 和 Safari on iOS 尚不支持该属性

参考

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy

加head标记

HTML代码

在静态网页的 头部 代码中【即 head 标记】添加如下配置项:

<meta name="referrer" content="no-referrer" />

它的作用就是阻止浏览器发送 Referer 信息,对整个页面的所有链接生效【当然也有针对单个链接设置的方法:<a rel=”noreferrer” href=”your-website-url” />,这里不采用】,这样一来微博图床就不知道请求的引用来源了,可以达到和直接在浏览器中访问一样的效果。 但是要注意,不是每种浏览器都支持这种语法的,此设置对有的浏览器来说无效

缺点

如果你的网站使用了第三方统计,可能会导致第三方统计失效。

使用非安全协议的http图片地址

在以下几种情况下,Referer 不会被发送

  • 来源页面采用的协议为表示本地文件的 file 或者 data URI
  • 当前请求页面采用的是非安全协议,而来源页面采用的是安全协议【HTTPS】
  • 为整个页面设置
  • 为单个链接设置

其中第二种情况,如果你的网站开启了 SSL,可以使用 HTTP 的图片链接,就可以正常访问了。

缺点

要牺牲你的网站的安全性,因为浏览器会检测到你的网站内容里面有普通的 HTTP 链接,就会导致不可信【尽管存在有效的证书,也没有用】,小绿锁会消失,并给出警告。

防御方法

  1. 不允许referer为空(不建议,因在某些开启隐私模式的浏览器中,或https页面引用下,referer是空的);
  2. 地址变更(lighttpd的是根据有效时间,nginx的根据是md5);
  3. 登录校验(如必须登录网站帐号后才能访问);