关于防盗链:网络安全前端程序员务必掌握的图片防盗链

原理在 http 协定申请中 header 里会带个 Referer 字段。通过图片服务器查看 Referer 是否来自规定的域名(白名单),而进行防盗链。 在浏览器中输出防盗链图片地址是能间接拜访的。 简略实现防盗链图片能够通过 nginx 配置白名单列表,不在白名单则返回 403 或者相应的解决(重定向到显示403的图片,等操作) location ~* \.(gif|jpg|jpeg|png|bmp|swf|flv)$ { valid_referers none blocked *.andyhu.com server_names ~\.google\. ~\.baidu\.; if ($invalid_referer) { return 403; #rewrite ^/ http://www.xxx.com/403.jpg; }}以上所有来自 *.andyhu.com 域名和域名中蕴含 google 和 baidu 的站点都能够拜访以后站点的gif|jpg|jpeg|png|bmp|swf|flv文件资源。其余起源域(不在白名单列表)名拜访则返回 403。如果被正文的 rewrite 则返回一张 403.jpg 的图片 显示第三方防盗链图片顺这浏览器能间接拜访防盗链图片的思路,不难发现,只有申请头 header 外面不携带 Referer 就能失常拜访到防盗链的资源。 1.全局下 申请都不带 referer <meta name="referrer" content="no-referrer" />题目含意no-referrer整个 Referer 首部会被移除。拜访起源信息不随着申请一起发送。no-referrer-when-downgrade在等同安全级别的状况下,援用页面的地址会被发送(HTTPS->HTTPS),然而在降级的状况下不会被发送 (HTTPS->HTTP)。origin在任何状况下,仅发送文件的源作为援用地址。例如 example.com/page.html 会将 example.com/ 作为援用地址。origin-when-cross-origin对于同源的申请,会发送残缺的URL作为援用地址,然而对于非同源申请仅发送文件的源。same-origin对于同源的申请会发送援用地址,然而对于非同源申请则不发送援用地址信息。strict-origin在等同安全级别的状况下,发送文件的源作为援用地址(HTTPS->HTTPS),然而在降级的状况下不会发送 (HTTPS->HTTP)。strict-origin-when-cross-origin对于同源的申请,会发送残缺的URL作为援用地址;在等同安全级别的状况下,发送文件的源作为援用地址(HTTPS->HTTPS);在降级的状况下不发送此首部 (HTTPS->HTTP)。unsafe-url无论是同源申请还是非同源申请,都发送残缺的 URL(移除参数信息之后)作为援用地址。MDN相干文档(更具体)小插曲(没有微信H5领取的需要能够忽视次插曲)有次我我的项目中为了拜访第三方防盗链图片,加了这行代码。而后我的项目中用到了微信 H5 领取,而微信 H5 领取是须要通过从 referer 中获取以后调起H5领取的域名与申请H5领取时提交的受权域名判断域名是否统一的。所以导致我我的项目中微信领取始终提醒 “商家存在未配置的参数”微信H5领取报错:“商家存在未配置的参数,请分割商家解决” ...

July 20, 2022 · 1 min · jiezi

前端解决第三方图片防盗链的办法-html-referrer-访问图片资源403问题

问题笔者网站的图片都是上传到第三方网站上的,比如 简书、掘金、七牛云上的,但是最近简书和掘金都开启了 防盗链,防止其他网站访问他们网站上的图片了,导致笔者的网站存在他们网站上的图片全挂了。 具体问题,就是 html 中通过 img 标签引入一个第三方的图片地址,报 403 。但是这个图片地址直接复制出来在地址栏打开,却是看得到的。 原因官方输出图片的时候,判断了来源 Referer ,就是从哪个网站访问这个图片,如果是你的网站去加载这个图片,那么 Referer 就是:你的网站地址; 如果我们的网站地址不在官方的白名单内,所以就看不到图片了。 我们做这个跳板的关键:不发送 Referer,也就是没有来源。那么官方那边,就认为是从浏览器直接访问的,所以就能加载正常的图片了。 解决方案如原网址: http://mmbiz.qpic.cn/mmbiz/DU... 显示此图片来自微信公众平台,未经允许不得应用 方法:在 <head> 标签里加 meta <meta name="referrer" content="never">这样存在第三方网站上的图片,在你的网站上就可以访问了。 referrer在某些情况下,出于一些原因,网站想要控制页面发送给 server 的 referrer 信息的情况下,可以使用这一 referer metadata 参数。 参数 referer 的 metedata 属性可设置 content 属性值为以下集合: neveralwaysorigin结果 如果 referer-policy 的值为 never:删除 http head 中的 referer;如果 referer-policy 的值为 default:如果当前页面使用的是 https 协议,而正要加载资源使用的是普通的 http 协议,则将 http header 中额 referer 置为空;如果 referer-policy 的值 origin:只发送 origin 部分;如果 referer-policy 的值为 always:不改变 http header 中的 referer 的值;举例 ...

June 9, 2019 · 1 min · jiezi

php伪造Referer请求反盗链资源

有些产品为了防止自己的产品被盗链访问,会采用反盗链措施,如封闭型生态的音乐网站和视频网站,他们已经为了版权付费,自然不希望你免费使用他们的资源。但因为很多人专门研究盗链,因此我们也需要了解下盗链、反盗链和逃避反盗链的原理。盗链引用百度百科对盗链的定义:盗链是指服务提供商自己不提供服务的内容,通过技术手段绕过其它有利益的最终用户界面(如广告),直接在自己的网站上向最终用户提供其它服务提供商的服务内容,骗取最终用户的浏览和点击率。受益者不提供资源或提供很少的资源,而真正的服务提供商却得不到任何的收益。常规盗链我们知道,网站提供服务是向服务端请求一个html文件,这个文件中包含有css/js文件,也包含img/video标签,这些静态资源会在html文件加载时,依次的发起请求并填充在指定位置上,从而完成整个页面的加载。因此只要拿到这个图片的URL并嵌入我们自己的html文件中,就能在我们的网站上访问,由于资源是不同的HTTP请求独立访问的,因此我们也能过滤源站的html文件。这就是最简单的盗链。危害:在用户访问时,并没有在访问被盗链网站,但是依然会占用该网站的带宽资源,而带宽是要给运营商付费的。同时,该网站的广告、周边、宣传等资源并不会被用户访问到。分布式盗链分布式盗链比较复杂,需要在服务端部署专门的程序,并不针对单个网站或单个url,而是对全网的所有有用的资源进行盗取,并存储在自己的数据库中,并在用户实际访问时,完全转换为自己的流量。危害:自己通过劳动、金钱、版权付费得到的资源,被盗链网站免费使用,如网店摄影图、期刊、电视剧等。并因此导致自己的会员、服务无法实现盈利。反盗链分类我们了解了盗链对源站的危害后,自然要通过一些手段来阻止这种行为维护自己的利益。加水印这是最简单的方法,通过后端程序批量对图片等资源加上水印,这样在盗链的同时,也在为自己的网站做宣传,有时甚至会主动寻求这种盗链。资源重命名因为盗链是通过指定的url,这个url中一定包含该资源的路径和名称,因此通过不定期的更改文件或目录的名称,能够快速避免盗链,但也会导致正在下载的资源被中断。限制引用页在http请求的头部信息中,有一个字段:referer,它代表这个请求是从哪个页面发起的,如果是单独在页面中打开或者服务端请求的,则这个字段为空。因此我们可以通过referer这个字段的值做限制,如果是自己认可的页面,则返回资源,否则,禁止该请求。但是由于每次都要打开一个白名单的文件做url匹配,因此会降低性能。加密认证在客户端通过将用户认证的信息和资源的名称进行组合后加密,将加密的字符串作为url的参数发起请求,在服务端进行解密并认证通过后,才会返回请求的资源。这个方式主要用于防范分布式盗链。反盗链程序上面的3种反盗链方式,我们常用的是第三种,通过referer属性来完成反盗链,今天也主要分享这一种方法的反盗链与防反盗链。后端程序限制这种限制需要消耗服务端计算资源,因此不如Nginx限制常用。$from = parse_url($_SERVER[‘HTTP_REFERER’]);if ($from[‘host’]!=‘xxx.com’ && $from[‘host’]!=‘www.xxx.com’) { die(‘你丫在盗链’);}Nginx限制通过修改nginx配置文件可以做到,修改完成后记得重启nginx:// 这里指定需要防盗链的资源,如gif/jpg等location ~* .(gif|jpg|png|jpeg)$ { // 设置资源的过期时间 expires 30d; // 设置合法的引用页,也就是防盗链的白名单; // none blocked保证用户在新页面打开时依然能够打开,如果不希望用户能够保存删掉这两项 valid_referers none blocked *.hugao8.com *.baidu.com *.google.com; // 对于非法的引用页,可以重写图片,也可以直接返回403或404页面 if ($invalid_referer) { rewrite ^/http://www.it300.com/static/images/404.jpg; #return 404; }}Referer-PolicyReferer 首部包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的。服务端一般使用 Referer 首部识别访问来源,可能会以此进行统计分析、日志记录以及缓存优化等。Referer属性出现在请求头中,也在请求头中被设置,但是在浏览器的安全策略里,该值无法被js所指定:$.ajax({ url: ‘http://www.baidu.com’, beforeSend(xhr) { // 在发送ajax请求前设置header头部 xhr.setRequestHeader(“Referer”, “http://translate.google.com/"); xhr.setRequestHeader(“User-Agent”, “stagefright/1.2 (Linux;Android 5.0)”); }, success(data) { console.log(data); }, error(err) { console.log(err); }});然而浏览器会报错:那么Referer是怎么被自动设置的呢?这个得看Referer-Policy属性是怎么定义的:no-referrer: 整个 Referer 首部会被移除。访问来源信息不随着请求一起发送。no-referrer-when-downgrade(默认值): 在没有指定任何策略的情况下用户代理的默认行为。在同等安全级别的情况下,引用页面的地址会被发送(HTTPS->HTTPS),但是在降级的情况下不会被发送 (HTTPS->HTTP)。origin: 在任何情况下,仅发送文件的源作为引用地址。例如 https://example.com/page.html 会将 https://example.com/ 作为引用地址。origin-when-cross-origin: 对于同源的请求,会发送完整的URL作为引用地址,但是对于非同源请求仅发送文件的源。same-origin: 对于同源的请求会发送引用地址,但是对于非同源请求则不发送引用地址信息。strict-origin: 在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS),但是在降级的情况下不会发送 (HTTPS->HTTP)。strict-origin-when-cross-origin: 对于同源的请求,会发送完整的URL作为引用地址;在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS);在降级的情况下不发送此首部 (HTTPS->HTTP)。unsafe-url: 无论是同源请求还是非同源请求,都发送完整的 URL(移除参数信息之后)作为引用地址。这个值可以通过三种方式来设置:<meta name=“referrer” content=“origin”><a href=“http://example.com” referrerpolicy=“origin”><a href=“http://example.com” rel=“noreferrer”>防反盗链前端JS不能在头部设置Referer字段,和跨域一样是因为浏览器的安全策略,那么同样的在服务端进行请求就不会有这些限制,我们在服务端请求时就可以自由的修改Referer字段。我们通过简单的PHP例子来完成这个功能:<?php$url = ‘http://t11.baidu.com/it/u=3008889497,862090385&fm=77';$refer = ‘https://www.baidu.com’;$ch = curl_init();//以url的形式 进行请求curl_setopt($ch, CURLOPT_URL, $url);//以文件流的形式 进行返回 不直接输出到浏览器curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//浏览器发起请求 超时设置curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);//伪造来源地址 curl_setopt ($ch, CURLOPT_REFERER, $refer);$file = curl_exec($ch);curl_close($ch);header(‘Content-Type: text/html’);// 对图片进行base64编码,然后返回给前端展示$file = base64_encode($file);echo “<img src=‘data:image/jpeg;base64,{$file}’ />”;?>我们第一次请求注释了伪造来源地址这一行,第二次请求不注释这一行,这样可以验证执行结果:总结盗链和反盗链是一个对立面,技术不断升级,最终的目标也是为了开放资源和保护知识产权。在互联网生态里,我们通过反盗链保护我们的利益,也使用防反盗链的这种方式来扩大我们的内容,无论站在哪一方,都需要做到知己知彼。参考文章百科-盗链:https://baike.baidu.com/item/…php防盗链:https://segmentfault.com/q/10…Referer伪造:https://zhuanlan.zhihu.com/p/…nginx防盗链:https://www.jianshu.com/p/979… ...

January 23, 2019 · 1 min · jiezi