防御 XSS 攻击的简单内容安全策略

 

最近几周,我们在博客上介绍了许多与安全相关的 HTTP 标头,但其中最重要的还是内容安全策略(CSP)。说它是 “老大”,是因为它提供的保护级别,但不幸的是,它也很难在第一时间正确实施。与我们最近讨论的所有 flightPATH 流量管理规则一样,我们自己也使用它们来保护 edgeNEXUS 网站及其访问者。

我们付出了艰辛的努力,也感受到了痛苦,所以你不必这样做,但不可否认的是,在实施之前需要进行一些思考和规划。但这是值得的。这个页眉背后的概念非常简单,但同样强大。简而言之,您可以用它来指定允许在网站上加载的内容的来源。这可以有效防止当今日益活跃的互联网上普遍存在的一系列代码注入攻击,如跨站脚本攻击(XSS)和点击劫持(Clickjacking)。

可控制的内容类型包括:JavaScript、CSS(是的,CSS 可能很危险)、HTML 框架、字体、图像和可嵌入对象(如 Java 小程序)。有如此多的选择固然很好,但这也是困难所在。如今的网站(包括我们的网站)包含来自许多来源的多种类型的内容,要在政策中识别和说明所有这些内容是一项相当艰巨的任务。

在讨论这个问题之前,我们先来看看标头值的元素和策略的样子。正如你所看到的,它基本上是一长串内容类型(本例中均以 -src 结尾)和每种类型允许的来源。这些内容统称为策略指令。

default-src ‘self’ data:; script-src ‘self’ ‘unsafe-inline’; connect-src ‘self’; img-src ‘self’ data:; style-src ‘self’ ‘unsafe-inline’ data:; font-src ‘self’ data:; child-src ‘self’

我们还可以考虑更多的内容类型,但上述内容是最重要的指令(在我们看来,是基于风险和普遍性)。下面详细介绍了每种类型所涉及的内容;

  • default-src– 如果稍后未指定,大多数(但不是所有)内容类型的默认值
  • script-src– 允许的脚本(包括 JavaScript)来源
  • connect-src – 允许的连接源(如聊天应用程序等使用的 WebSockets 和 EventSource)
  • img-src– 允许的图像来源
  • style-src– CSS 的允许来源
  • font-src– 允许的字体来源
  • child-src– 框架和 iframe 的允许来源

这些内容类型及其值之间用分号隔开(分隔)。每种类型可以有一个或多个以下值;

  • 无”允许使用此内容类型
  • 自我”–如果内容直接来自本网站(但不包括子域),则允许使用该内容类型
  • 不安全内联”–允许内联 CSS 和 JavaScript(不幸的是,这种情况非常普遍)
  • 数据:– 允许内联数据源(通常用于提供内联字体和图像,以提高性能)
  • https:– 仅允许在 HTTPS 上使用此内容类型
  • 不安全-eval”–允许使用可能导致执行代码的潜在危险方法解析文本
  • 域名– 如果该内容类型来自指定的域名(换句话说,一个远程域),则允许使用该内容类型 – 可多次使用
  • * – 任何域

每个值之间用一个空格分隔。除非值是域名,否则必须使用单引号’。请注意,浏览器扩展和插件不在此列,因为它们被认为是安全的,因为它们受到用户的信任(毕竟是用户安装的)。

这一切看起来都相当专业和复杂,但如果我们一步一步来,很快就能制定出政策。让我们通过两个例子来快速解决这个问题。首先,让我们试试通过 HTTP 提供服务的简单内部网站。下面是我们需要的内容;

  • default-src ‘self’ 数据:– 只允许来自我们自己网站的内容,包括内联对象
  • script-src ‘self’ ‘unsafe-inline’– 允许使用我们自己网站的脚本,包括内联脚本
  • connect-src ‘self’– 允许从我们自己的网站连接/向我们自己的网站连接
  • img-src ‘self’ 数据: – 允许来自我们自己网站的图片,包括内联图片
  • style-src ‘self’ ‘unsafe-inline’ data: – 允许来自我们自己网站的 CSS,包括内联样式
  • font-src ‘self’ 数据:– 允许字体来自我们自己的网站,包括内联字体

全标题值相当短:

default-src ‘self’ data:; script-src ‘self’ ‘unsafe-inline’; connect-src ‘self’; img-src ‘self’ data:; style-src ‘self’ ‘unsafe-inline’ data:; font-src ‘self’ data:

第二,受 SSL/TLS 保护的面向互联网的网站,该网站使用 Google Analytics (GA)、内联 CSS、字体和图像,其中 CSS 来自您的网站,图像来自其他网站。让我们逐一讨论我们需要什么(其实差别不大);

  • default-src ‘self’ data: https:– 仅允许来自我们自己网站的内容(包括内联对象)通过 HTTPS 传输
  • script-src ‘self’ ‘unsafe-inline’ https:– 仅通过 HTTPS 允许来自我们自己网站的脚本,包括内联脚本
  • img-src ‘self’ ‘unsafe-inline’ \* https: – 仅通过 HTTPS 允许来自任何网站的图像,包括来自我们网站的内联图像
  • style-src ‘self’ ‘unsafe-inline’ https:– 仅允许通过 HTTPS 从我们自己的网站获取 CSS,包括内联 CSS
  • font-src ‘self’ ‘unsafe-inline’ https:– 仅允许通过 HTTPS 从我们自己的网站获取字体,包括内联字体

所有这些加在一起,我们就有了这份稍长的政策:

default-src ‘self’ data: https:; script-src ‘self’ ‘unsafe-inline’ *.google-analytics.com https:; img-src ‘self’ ‘unsafe-inline’ * https:; style-src ‘self’ ‘unsafe-inline’ https:; font-src ‘self’ ‘unsafe-inline’ https:

我觉得很简单。谷歌过去对 CSP 并不 “友好”(这个头值过去至少是现在的两倍),但值得庆幸的是,他们最近取得了长足进步。您会注意到,我们无需将 *.google-analytics.com 域作为内容类型值添加到 script-src 中,因为他们的代码是作为内联脚本运行的。

理想情况下,您会为网站上的每个页面创建一个策略,因为每个页面加载的资源无疑是不同的,但这样做相当繁琐,而创建一个涵盖所有可能来源的策略要简单得多,但仍然有效。我们 GitHub 页面上的大多数示例都采用了这种方法,但如果您想为特定页面提供更多保护,这里也有一个示例。

为了测试和排除故障,我强烈建议使用谷歌 Chrome 浏览器的 “开发工具”。访问相关网站,然后点击 F12,单击网络,确保已勾选禁用缓存,然后重新加载页面。任何错误都会清楚地显示出来。本博客底部有一个屏幕,显示了如果你的策略阻止了不安全内联,而你正在使用 Google Analytics,你可能会看到的错误信息;这些错误信息非常有用。

必要时调整策略,然后重复上述步骤。理想情况下,您可以使用一个专用的测试虚拟服务,并应用您正在测试的 flightPATH 规则,但在其他方面为相同的网站提供服务,只是通过不同的虚拟 IP,这样就不会在测试时影响真实客户和客户端。

与往常一样,使用负载平衡器的巨大优势在于,我们只需在一个中心位置进行操作,即可保护我们的所有服务器(和网站)。我们不需要依赖开发人员或网络服务器重新配置。在 edgeNEXUS 负载均衡器上,我们只需导入 jetPACK 自动配置模板,并将 flightPATH 流量规则分配给我们希望保护的虚拟服务(经过适当修改后)。

该规则只在页眉不存在的情况下添加页眉,因此即使我们的网络服务器已经插入页眉,或者只在特定页面插入页眉,它也能正常工作。该规则应成为标准虚拟服务配置的一部分–无论网站如何,您都不会有任何损失,当然,我们始终建议您进行测试。您可以在edgeNEXUS Github 网站上下载此 jetPACK 和其他许多软件。

flightPATH 是 edgeNEXUS 开发的基于事件的动态规则引擎,可智能地处理和路由负载平衡的 IP、HTTP 和 HTTPS 流量。它具有高度可配置性,功能强大,而且非常易于使用。

如果您想了解更多信息,这些相关链接非常值得一读;

http://www.html5rocks.com/en/tutorials/security/content-security-policy/

https://developer.mozilla.org/en/docs/Web/Security/CSP/CSP_policy_directives

http://content-security-policy.com/

https://www.clickintelligence.co.uk/header-response-checker/

最近几周,我们在博客上介绍了许多与安全相关的 HTTP 标头,但其中最重要的还是内容安全策略(CSP)。

About Donna Toomey