Referer和Referrer Policy详解
最近换了个负责网络安全的leader,整个部门开始网络安全整顿,我们负责WEB的接到通知要求防御CSRF攻击,设置referer白名单。之前看过一点referer相关的,但是了解不够深入,趁这次机会好好了解了一下。1. 什么是 RefererReferer 是 HTTP 请求头的一个字段,当浏览器(或者模拟浏览器行为)向服务器发送请求时,浏览器会自动在请求头中加上 Referer 字段,表示的意思
最近换了个负责网络安全的leader,整个部门开始网络安全整顿,我们负责WEB的接到通知要求防御CSRF攻击,设置referer白名单。之前看过一点referer相关的,但是了解不够深入,趁这次机会好好了解了一下。
1. 什么是 Referer
Referer
是 HTTP 请求头的一个字段,当浏览器(或者模拟浏览器行为)向服务器发送请求时,浏览器会自动在请求头中加上 Referer
字段,表示的意思是链接的来源地址,比如在页面引入图片、JS 等资源,或者跳转链接,一般不修改策略,都会带上Referer。
比如在www.google.com 里有一个www.baidu.com 链接,那么点击这个www.baidu.com ,它的header 信息里就有:Referer=http://www.google.com
这里有个问题要说明下,Referer
实际上是单词 referrer
的错误拼写,Referrer-Policy
这个首部并没有延续这个错误拼写。
2. Referer 安全性
Referer
参数其实就告诉了链接的请求来源于哪个网站,所以可以根据这个特性,限制一些接口只能本网站的才能调,外部网站不能调。
这个参数常常是跟同源策略和跨域请求关联在一起,因为现在普遍都是前后端分离项目, 前端页面的地址和后端 api 接口地址是跨域的,为了让后台接口判断是不是合法请求,除了前端在请求头中加上 Authorization 字段,后台也可以通过 Referer
字段判断请求来源。
另外,在 CSRF 攻击的防范中,除了 SameSite Cookie ,CSRF token 等方法,Referer
字段判断请求来源也是一种防范手段。
3. 什么是 Referrer-policy
Referrer Policy是W3C官方提出的一个候选策略,主要用来规范Referrer,简单来说就是规定什么时候发送 Referer
字段,以及发送哪些信息。
最初是只有5种策略的,现在规范增加到9种:
no-referrer
整个 Referer
首部会被移除,Referer
不随着请求一起发送。
no-referrer-when-downgrade (默认值)
在没有指定任何策略的情况下用户代理的默认行为。在同等安全级别(HTTPS -> HTTPS)的情况下,Referer
会被发送,在协议降级(HTTPS -> HTTP)的情况下 Referer
不会被发送。
origin
Referrer
发送的信息只包括协议+域名+端口,不包括其它信息。例如 https://example.com/page.html
会将 https://example.com/
作为引用地址。
origin-when-cross-origin
对于同源的请求,会发送完整的URL作为引用地址,但是跨域时候只发送协议+域名+端口。
same-origin
同源请求发送,否则不发送。
strict-origin
在同等安全级别(HTTPS -> HTTPS)的情况下,发送Referrer(协议+域名+端口),但是在协议降级(HTTPS -> HTTP)的情况下不会发送。
strict-origin-when-cross-origin
对于同源的请求,会发送完整的URL作为引用地址;对于跨域请求,在同等安全级别(HTTPS -> HTTPS)的情况下,发送Referrer(协议+域名+端口);在协议降级(HTTPS -> HTTP)的情况下不发送此首部。
unsafe-url
无论协议是否降级,也不管是同源请求还是跨域请求,都发送完整的 URL(移除参数信息之后)作为引用地址,所以这种是一种不安全的协议。
这项设置会将受 TLS 安全协议保护的资源的源和路径信息泄露给非安全的源服务器。进行此项设置的时候要慎重考虑。—— Referrer-Policy,MDN文档
空字符串
相当于没有设置,在没有此类更高级别策略的情况下,默认使用 no-referrer-when-downgrade
。
4. Referrer-policy 使用方法
加在 Header 中
代码如下:
<script>
fetch(url, {referrerPolicy: "strict-origin-when-cross-origin"});
</script>
有一个疑问,在浏览器调试工具中,Referrer Policy
出现在 General 里面,并没有出现在请求或者响应的报文中,所以无法判断是在请求头还是响应头中。
MDN文档上说 Referrer Policy
是响应头中的字段,但我个人觉得如果是在响应头里面,请求都发出了,再响应这个字段也没啥用了。而如果是放在请求头里面,这个字段的作用是修改浏览器处理 Referer
的行为,提交给服务器也没啥用啊。
于是用Wireshark抓包工具看了一下报文信息,发现请求的时候只有 Referer
,没有 Referrer Policy
,说明这个字段并没有在实际请求的时候发送,也没有通过服务器响应接收:
所以 Referrer Policy
应该可以理解为浏览器自己的一个配置项,在构造 ajax 请求的时候可以添加到 header 中,这个配置项用于修改浏览器处理 Referer
的行为,但不会放到实际的 header 中发送给服务端。
页面设置
现在很多前端项目都是单页应用,可以在入口文件 index.html
中的 <head>
标签中添加 meta 信息:
<meta name="referrer" content="strict-origin-when-cross-origin">
元素设置
在html元素中设置 referrerpolicy
:
<a href="http://example.html" referrerpolicy="origin" target="_blank">链接</a>
<img src="/example.jpg" referrerpolicy="strict-origin-when-cross-origin" />
Referrer-Policy是有一个优先级顺序的:
-
Element-level policy
-
Page-level policy
-
Browser default
元素级别的策略优先级最高,页面级别的次之,浏览器默认值最低。所以,可以先设置一个较严格的页面级策略,再对某些资源做渐进增强。
5. Referer 应用场景
- 防盗链
- 防止恶意请求
参考:
Referrer-Policy MDN 官方文档
HTTP系列之Referer和Referrer policy简介
http请求头中Referer的含义和作用
HTTP的Referrer和Referrer Policy设置
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)