如何使用 HTTP Headers 来保护你的 Web 应用( 三 )


X-XSS-Protection 指令包括:

  • 1 或者 0
使用或禁用 XSS 过滤器 。
  • mode=block
当检测到 XSS 攻击时,这会指示浏览器不渲染整个页面 。
我建议永远打开 XSS 过滤器以及 block 模式,以求最大化保护用户 。这样的响应头应该是这样的:
X-XSS-Protection: 1; mode=block复制代码以下是在 Node.js 中配置此响应头的方法:
function requestHandler(req, res){res.setHeader('X-XSS-Protection','1;mode=block');}复制代码控制 iframeiframe (正式来说,是 HTML 内联框架元素)是一个 DOM 元素,它允许一个 web 应用嵌套在另一个 web 应用中 。这个强大的元素有部分重要的使用场景,比如在 web 应用中嵌入第三方内容,但它也有重大的缺点,例如对 seo 不友好,对浏览器导航跳转也不友好等等 。
其中一个需要注意的事是它使得点击劫持变得更加容易 。点击劫持是一种诱使用户点击并非他们想要点击的目标的攻击 。要理解一个简单的劫持实现,参考以下 HTML,当用户认为他们点击可以获得奖品时,实际上是试图欺骗用户购买面包机 。
<html><body><button class='some-class'>Win a Prize!</button><iframe class='some-class' style='opacity: 0;’ src=https://www.isolves.com/it/wlyx/wzjs/2020-07-06/'http://buy.com?buy=toaster'>复制代码有许多恶意应用程序都采用了点击劫持,例如诱导用户点赞,在线购买商品,甚至提交机密信息 。恶意 web 应用程序可以通过在其恶意应用中嵌入合法的 web 应用来利用 iframe 进行点击劫持,这可以通过设置 opacity: 0 的 css 规则将其隐藏,并将 iframe 的点击目标直接放置在看起来无辜的按钮之上 。点击了这个无害按钮的用户会直接点击在嵌入的 web 应用上,并不知道点击后的后果 。
阻止这种攻击的一种有效的方法是限制你的 web 应用被框架化 。在 RFC 7034 中引入的 X-Frame-Options,就是设计用来做这件事的 。此响应头指示浏览器对你的 web 应用是否可以被嵌入另一个网页进行限制,从而阻止恶意网页欺骗用户调用你的应用程序进行各项操作 。你可以使用 DENY 完全屏蔽,或者使用 ALLOW-FROM 指令将特定域列入白名单,也可以使用 SAMEORIGIN 指令将应用的源地址列入白名单 。
我的建议是使用 SAMEORIGIN 指令,因为它允许 iframe 被同域的应用程序所使用,这有时是有用的 。以下是响应头的示例:
X-Frame-Options: SAMEORIGIN复制代码以下是在 Node.js 中设置此响应头的示例代码:
function requestHandler(req, res){res.setHeader('X-Frame-Options','SAMEORIGIN');}复制代码指定白名单资源如前所述,你可以通过启用浏览器的 XSS 过滤器,给你的 web 应用程序增强安全性 。然而请注意,这种机制是有局限性的,不是所有浏览器都支持(例如 Firefox 就不支持 XSS 过滤),并且依赖的模式匹配技术可以被欺骗 。
对抗 XSS 和其他攻击的另一层的保护,可以通过明确列出可信来源和操作来实现 —— 这就是内容安全策略(CSP) 。
CSP 是一种 W3C 规范,它定义了强大的基于浏览器的安全机制,可以对 web 应用中的资源加载以及脚本执行进行精细的控制 。使用 CSP 可以将特定的域加入白名单进行脚本加载、AJAX 调用、图像加载和样式加载等操作 。你可以启用或禁用内联脚本或动态脚本(臭名昭著的 eval),并通过将特定域列入白名单来控制框架化 。CSP 的另一个很酷的功能是它允许配置实时报告目标,以便实时监控应用程序进行 CSP 阻止操作 。
这种对资源加载和脚本执行的明确的白名单提供了很强的安全性,在很多情况下都可以防范攻击 。例如,使用 CSP 禁止内联脚本,你可以防范很多反射型 XSS 攻击,因为它们依赖于将内联脚本注入到 DOM 。
CSP 是一个相对复杂的响应头,它有很多种指令,在这里我不详细展开了,可以参考 HTML5 Rocks 里一篇很棒的教程,其中提供了 CSP 的概述,我非常推荐阅读它来学习如何在你的 web 应用中使用 CSP 。
以下是一个设置 CSP 的示例代码,它仅允许从应用程序的源域加载脚本,并阻止动态脚本的执行(eval)以及内嵌脚本(当然,还是 Node.js):
function requestHandler(req, res){res.setHeader('Content-Security-Policy',"script-src 'self'");}复制代码防止 Content-Type 嗅探为了使用户体验尽可能无缝,许多浏览器实现了一个功能叫内容类型嗅探,或者 MIME 嗅探 。这个功能使得浏览器可以通过「嗅探」实际 HTTP 响应的资源的内容直接检测到资源的类型,无视响应头中 Content-Type 指定的资源类型 。虽然这个功能在某些情况下确实是有用的,它引入了一个漏洞以及一种叫 MIME 类型混淆攻击的攻击手法 。MIME 嗅探漏洞使攻击者可以注入恶意资源,例如恶意脚本,伪装成一个无害的资源,例如一张图片 。通过 MIME 嗅探,浏览器将忽略声明的图像内容类型,它不会渲染图片,而是执行恶意脚本 。


推荐阅读