前篇“WEB安全防护相关响应头(上)”中,我们分享了 X-Frame-Options、X-Content-Type-Options、HTTP Strict Transport Security (HSTS) 等安全响应头的内容。下文中,我们则侧重介绍一些和跨站安全相关的响应头——

一、Referrer-Policy -- 不要问我从哪里来

“互联网”这个词,顾名思义,“互联”才有意义。我们看到的一个常规页面,往往是先加载父级页面,父级页面再加载其他的子资源(如图片、JS 文件和各种多媒体文件等);主页面上通常还有各种链接,点击会跳转到其他内容;另外,通过 < iframe > 等标签,还可以把第三方页面嵌入在父级页面里直接显示出来。这些都是内容之间“互联”的体现。



▲图1 一些做得好的 <iframe> 会和主页面融为一体,如右侧

在 HTTP 协议里,如果【A资源】发起了对【B资源】的互联请求,表明该请求来自【A资源】的信息会体现在【B资源】的「referer」请求头里。【B资源】就能明确知道发起方是【A资源】。只要是引用关系或者互联关系的请求,浏览器都会自动附加这个「referer」请求头,以标明发起端是谁。

这个请求头的本意,是让网站管理者更容易得知 HTTP 访问的来源。但人们逐渐认识到这个请求头有可能暴露使用者的隐私。譬如【A资源】当前的 URL 里,如果包含了比较敏感的用户名、权限和会话等信息;只要捕获【B资源】的「referer」请求头,就有可能获得用户在【A资源】里的敏感信息。


出于对保护隐私的考虑,Firefox 和 Chrome 等浏览器引入了一套更精确控制浏览器如何发送「referer」请求头的机制,名叫「Referrer-Policy」。支持这套机制的浏览器,会根据具体情况决定是否发送「referer」请求头。但值得注意的是:微软系列的浏览器IE和Edge都不支持这个机制

使用以下几种方式,可以加载和设定不同的「Referrer-Policy」策略:

方法一:

从 WEB 服务器端,整体地返回 Referrer-Policy 响应头:

#Nginx配置:
add_header Referrer-Policy "no-referrer" always; #Apache配置:
Header always set Referrer-Policy "same-origin"

方法二:

对整个页面添加一个名为"referrer"的新 meta 值,类似:

<meta name="referrer" content="origin">

方法三:

给页面内某个标签,如下例中的 <a> 链接标签和 <img> 图片加载标签,增加一个 referrerpolicy 属性:

<a href="http://example.com" referrerpolicy="origin">
<img src="http://www.baidu.com/img/bd_logo1.png" referrerpolicy="no-referrer">

可以看出,以上三种方式的生效范围各有差异,分别对应整站起效、特定页面起效及设置特定标签起效,可以根据具体情况使用。

这个策略可以配置为以下值,含义分别为:

  • no-referrer

    任何情况下,浏览器都不发送 HTTP referer 请求头;

  • no-referrer-when-downgrade

    如果浏览器从 HTTPS 类型的 URL 跳转到 HTTP 类型的 URL,浏览器就不需要发送 referer 请求头;

  • same-origin

    只有发起端和目标端是同源时,浏览器才发送 referer 请求头。域名和协议完全相同,两个站点才是同源站点;

  • origin

    浏览器会发送 referer 请求头,但 referer 请求头里只有发起方的域名信息,没有完整的 URL 路径。如发起端 URL 为 https://example.com/page.html,实际发送的 referer 请求头里只有 https://example.com/

  • strict-origin

    origin 含义相似,且只有同等安全级别的协议才发送 referer 请求头,如从 HTTPS→HTTPS 会发送,而从 HTTPS→HTTP 则不发送;

  • origin-when-cross-origin

    对同源的其他资源,发送包含完整 URL 的 referer 请求头;如果是非同源的资源,则 referer 请求头里只有域名信息,没有完整 URL;

  • strict-origin-when-cross-origin

    和上一条类似,但协议的安全等级降低时就不发送 referer 请求头了;

  • unsafe-url

    无论是否同源,都发送完整 URL 的 referer 请求头。

举例:在我们的测试页面 http://www.sandbox.com/index.html 里,包含外站图片 http://img.tcxa.com.cn/logo.png 。默认在没有其他设置的情况下,发往该图片的请求如下图,其中的 Referer 请求头里清晰地包含了父级页面的地址:http://www.sandbox.com/index.html



▲图2 正常状态下图片访问带referer请求头

如果 www.sandbox.com 服务器的 Nginx 配置内,加入 add_headerReferrer-Policy"same-origin"always; ,设定只有同源站点才发送 Referer 请求头。这时候,访问 http://www.sandbox.com/index.html 获得的响应头里,就增加了一行 Referrer-Policy:same-origin 的响应头,如下:



▲图3 父资源的Referrer-Policy设置为same-origin同源

这时候,由于和发起端 www.sandbox.com 的域名并不同源,如下图所示,可以看出,发往 http://img.tcxa.com.cn/logo.png 图片的请求此时已不再出现 Referer 请求头了:



▲图4 子资源的请求里不再包含Referer请求头

题外话:

referer 这个单词在英语里并不存在,它是个拼错的单词,正确写法是「referrer」。在相关 HTTP 协议制定时,写作者笔误写错了。人们意识到这个错误时为时已晚。为了保持旧有兼容性,这个名字被将错就错延续下来。但后续很多和 referer 请求头相关的术语和协议,又恢复了正确的「referrer」拼法。比如这里的「Referrer-Policy」策略。

二、X-XSS-Protection -- 跨站边界保护

XSS 的全称是 Cross Site Scripting,中文叫“跨站脚本攻击”。其中“脚本”一词,主要指 JavaScript 脚本。JavaScript 脚本在多年的进化中,使用越来越灵活,功能越来越强大,这也导致人们原本不太在意的浏览器客户端安全,变得越来越重要了。

现在的 JavaScript 脚本,不但可以访问和操控页面上的 DOM 元素,还可以和服务器端进行交互,故而它带来的安全隐患也不容忽视。为了“缓解”这一问题,浏览器厂商们做了一定的努力,其中一种机制就是 X-XSS-Protection 响应头。支持这一响应头的浏览器,在检测到跨站脚本攻击 (XSS)时,可以主动停止加载页面。

这个响应头有以下四种值:

X-XSS-Protection: 0
X-XSS-Protection: 1
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; report=<reporting-uri>

这四个值的含义分别为:

  • 0 :禁用对页面的 XSS 过滤功能;
  • 1 :启用对页面的 XSS 过滤功能,这也是浏览器默认的处理(不需要做任何配置,就是这个选项)。如果发现有 XSS 风险的代码,浏览器就自动清理页面,去除这部分有危害的代码;
  • 1;mode=block :启用对页面的 XSS 过滤功能,但在发现 XSS 风险时,会直接屏蔽整个页面的展示,而不是只去除有风险部分;
  • 1;report=<reporting-URI> :启用对页面的 XSS 过滤功能,如果发现有 XSS 风险的代码,浏览器就自动清理页面,去除这部分有危害的代码,同时,把有问题的事件缘由提交给指定的 URL。

我们用 DVWA 的跨站演示页面,来分别展示一下,响应头设置为上述几个不同值时,对应的不同效果。

以下三次测试,都是提交了完全一样的请求:

http://dvwa站点IP/vulnerabilities/xss_r/?name=<script>alert(document.cookie)</script>

测试一

设置 X-XSS-Protection:0

X-XSS-Protection:0 时,浏览器直接执行了有问题的网页端代码,所以,提交的内容里的 JavaScript 代码能成功执行,在浏览器里看到了弹窗效果,弹窗内容为浏览器访问当前网站的 Cookie 值,参见图5。这种设置仅适用于安全渗透测试练手,以及希望准确评估网站安全风险代码时使用。



▲图5 JavaScript代码执行成功,看到弹窗

测试二

设置 X-XSS-Protection:1

这是默认设置。也就是说,如果服务器端完全没有返回过 X-XSS-Protection 响应头,浏览器就认为服务器端返回的是 X-XSS-Protection:1 。这时候,浏览器会根据自己的内部过滤原则,直接无视它认为有问题的那部分代码,自动跳过这部分代码(这部分内容根本不会发给服务器端),最终我们看到的是“清理”后的效果:



▲图6 JavaScript代码没有执行成功,没有弹窗

测试三

设置 X-XSS-Protection:1;mode=block

这是最严厉的设置。这时候,浏览器会根据自己的内部过滤原则,发现有问题代码,直接就拒绝显示该页面,这次提交也不会被发往服务器端,效果如图:



▲图7 整个页面都无法显示了

以上三种设置,可以根据具体的需求做选择。

如果需要在服务器端设置这个响应头,可以在合适的范围内,加入以下指令:

#Nginx配置:
add_header X-XSS-Protection "1; mode=block" always; #Apache配置:
Header always set X-XSS-Protection "1; mode=block"

那么,是不是我们只要给服务器设置好这个响应头,就能彻底解决跨站脚本攻击的问题呢?答案有点令人丧气:并不一定!这个机制的定位仅仅是“缓解”跨站脚本攻击,它不是一颗银子弹,无法就此高枕无忧了。一方面,跨站脚本攻击有非常多的变型手法和实现,业界公认没法完全通过黑名单规则来彻底过滤跨站——要彻底防护跨站脚本攻击,就几乎需要抵触互联网的“互联”本质。所以,X-XSS-Protection 的机制,也只是对跨站脚本攻击的部分防护。

另一方面,也请阅读附录“参考”里的第4条链接里的内容。这位作者对 X-XSS-Protection:1 的设置尤为意见大,因为攻击者反而有可能巧妙地利用这个机制,使网站需要正常使用的 JavaScript 脚本,被 X-XSS-Protection 机制判断为有危害,导致整个 JavaScript 脚本无效,又引入其他的安全问题。所以他的建议是,如果很确定自己的网站没有跨站问题或无法忍受自己的页面被误判有跨站,就设置 X-XSS-Protection:0;否则就明确禁用有问题的整个网页,使用 X-XSS-Protection:1;mode=block 设置项。

要对客户端进行更细粒度更有效的安全防护,目前更建议使用的机制是 CSP (Content Security Policy)。这个又需要一篇独立的文档来介绍了,敬请期待。

(朱筱丹 | 天存信息)

Ref

  1. Referrer Policy’ - Editor’s Draft, 20 April 2017
  2. Referrer-Policy’ - developer.mozilla
  3. X-XSS-Protection’ - developer.mozilla
  4. The Misunderstood X-XSS-Protection

WEB安全防护相关响应头(下)的更多相关文章

  1. WEB安全防护相关响应头(上)

    WEB 安全攻防是个庞大的话题,有各种不同角度的探讨和实践.即使只讨论防护的对象,也有诸多不同的方向,包括但不限于:WEB 服务器.数据库.业务逻辑.敏感数据等等.除了这些我们惯常关注的方面,WEB ...

  2. Web安全 之 X-Frame-Options响应头配置

    最近项目处于测试阶段,在安全报告中存在" X-Frame-Options 响应头缺失 "问题,显示可能会造成跨帧脚本编制攻击,如下图: X-Frame-Options: 值有三个: ...

  3. 转载:Web安全 之 X-Frame-Options响应头配置

    转自:https://blog.csdn.net/u013310119/article/details/81064943 项目检测时,安全报告中存在 “X-Frame-Options” 响应头缺失问题 ...

  4. 【译】在ASP.Net和IIS中删除不必要的HTTP响应头

    引入 每次当浏览器向Web服务器发起一个请求的时,都会伴随着一些HTTP头的发送.而这些HTTP头是用于给Web服务器提供一些额外信息以便于处理请求.比如说吧.如果浏览器支持压缩功能,则浏览器会发送A ...

  5. 在ASP.Net和IIS中删除不必要的HTTP响应头

    引入 每次当浏览器向Web服务器发起一个请求的时,都会伴随着一些HTTP头的发送.而这些HTTP头是用于给Web服务器提供一些额外信息以便于处理请求.比如说吧.如果浏览器支持压缩功能,则浏览器会发送A ...

  6. 在ASP.Net和IIS中删除不必要的HTTP响应头[转]

    http://www.cnblogs.com/CareySon/archive/2009/12/14/1623624.html 引入 每次当浏览器向Web服务器发起一个请求的时,都会伴随着一些HTTP ...

  7. http状态码 以及请求响应头相关

    1xx消息[编辑] 这一类型的状态码,代表请求已被接受,需要继续处理.这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束.由于HTTP/1.0协议中没有定义任何1xx状态码,所以除非 ...

  8. 如何使用 HTTP 响应头字段来提高 Web 安全性?

    在 Web 服务器做出响应时,为了提高安全性,在 HTTP 响应头中可以使用的各种响应头字段. X-Frame-Options 该响应头中用于控制是否在浏览器中显示 frame 或 iframe 中指 ...

  9. 通过 Jersey Http请求头,Http响应头,客户端 API 调用 REST 风格的 Web 服务

    原地址:http://blog.csdn.net/li575098618/article/details/47853263 Jersey 1.0 是一个开源的.可以用于生产环境的 JAX-RS(RES ...

随机推荐

  1. Day14_85_通过反射机制修改Class的属性值(IO+Properties)动态修改

    通过反射机制修改Class的属性值(IO+Properties)动态修改 import java.io.FileInputStream; import java.io.FileNotFoundExce ...

  2. 你已经用上 5G 网络了吗?

    随着各大手机厂商陆续推出 5G 手机,智能手机全面迎来 5G 浪潮.可能有人会发问:如此推崇 5G,5G 能为我们带来什么,我们的生活又会因此而改变多大呢? 什么是 5G? 简单地说,5G 就是第五代 ...

  3. Java | 使用OpenFeign管理多个第三方服务调用

    背景 最近开发了一个统一调度类的项目,需要依赖多个第三方服务,这些服务都提供了HTTP接口供我调用. 服务多.接口多,如何进行第三方服务管理和调用就成了问题. 常用的服务间调用往往采用zk.Eurek ...

  4. 深入浅出:MySQL的左连接、右连接、等值连接

    深入浅出:MySQL的左连接.右连接.等值连接 三种连接的语法 为便于更多的技友快速读懂.理解,我们只讨论2张表对象进行连接操作的情况,大于2张表对象进行的连接操作原理也是一样的. 1.左连接(LEF ...

  5. JavaScript 通过身份证号获取出生日期、年龄、性别 、籍贯

    JavaScript 通过身份证号获取出生日期.年龄.性别 .籍贯(很全) 效果图: 示例代码: //由于没有写外部JS,所以代码比较长!!! <!DOCTYPE html PUBLIC &qu ...

  6. hdu4784 不错的搜索( 买卖盐,要求整钱最多)

    题意:       给你一个有向图,每个节点上都有一个盐价,然后给你k个空间,么个空间上节点与节点的距离不变,但盐价不同,对于每一个节点,有三种操作,卖一袋盐,买一袋盐 ,不交易,每一个节点可以跳掉( ...

  7. UVA11388GCD LCM

    题意:       输入两个整数G,L,找出两个正整数a,b使得gcd(a ,b)=G,lcm(a ,b)=L,如果有多组解,输出最小的a的那组,如果没解,输出-1. 思路:       比较简单,如 ...

  8. RDPInception攻击手法

    在讲RDPInception攻击手段之前,我们先了解一下RDP远程桌面(Remote Desktop Protocol)协议.RDP远程桌面协议(Remote Desktop Protocol)是一个 ...

  9. 在 Peach 中使用发布者进行调试

    0x01 桃子平台 桃子平台(Peach)是一款流行的 Fuzz 平台,主要用作二进制文件及网络协议的模糊测试.其原理遵循基本的模糊测试流程,比较有特色的是它依赖用户所编写的 Pit 文件,同时输入的 ...

  10. layui在toolbar使用上传控件在reload后失效的问题解决

    问题描述 ​使用layui中的upload组件来上传文件,将按钮放了表格中的toolbar(头部工具栏中),碰到的问题是:第一次可以实现上传文件,但是第二次再上传文件的时候,点击按钮无效. 解决办法 ...