使用安全策略(CSP)的内容以安全的Web应用程序

内容安全政策(CSP)是一种计算机安全标准提供一个额外的层防止跨站点脚本(XSS),“点击劫持”和其他客户端攻击依赖于执行恶意内容可信上下文的web页面。本文展示了如何使用CSP头部保护网站对XSS攻击和其他试图绕过同源策略。

使用安全策略(CSP)的内容以安全的Web应用程序

内容安全政策(CSP)是一种计算机安全保护的标准,它提供了一个额外的层跨站点脚本(XSS),“点击劫持”和其他执行恶意代码注入攻击依赖于可信上下文的web页面的内容。通过使用合适的CSP指令在HTTP响应头,您可以有选择地指定数据源应该允许在您的web应用程序。本文展示了如何使用CSP头部保护网站对XSS攻击和其他试图绕过同源策略。

为什么我们需要CSP吗?

网络安全是基于同源策略(SOP)外,这可以防止一个网站访问数据自身的起源。从理论上讲,这应该足以确保安全,但现代web站点需要从外部来源包括大量的资产,如脚本和其他资源从内容分发网络(cdn),谷歌分析脚本,字体,风格,评论模块,社交媒体按钮——的例子不胜枚举。

同时,恶意黑客使用跨站点脚本(XSS)攻击诱骗用户网站可信传递恶意代码。没有额外的安全措施,浏览器执行所有代码从一个值得信赖的起源和不能告诉哪些代码是合法的,所以任何注入恶意代码的执行。

输入内容安全政策(CSP)——一组标准化的指示,告诉浏览器内容源是可以信任的,哪些应该被阻塞。使用精心定义的策略,您可以限制浏览器内容消除许多常见注射向量和显著降低XSS攻击的风险。默认情况下,CSP也为额外的安全实施现代脚本编码风格。

历史和浏览器支持

内容安全政策是一个候选人推荐的W3C工作组web应用程序安全性。版本1(或一级)于2012年提出,2级2014年后,3级自2015年以来,发展建议草案。只有一个建议,CSP很快实现通过浏览器厂商,从Firefox 4。绝大多数的现代浏览器支持所有或几乎所有二级指令,本文介绍了CSP 2级事实上的当前的标准。

CSP的实现使用了3种不同的内容安全政策标题名称,根据采用的浏览器和时间:

  • Content-Security-Policy:标准W3C推荐的标题名称和所使用的所有现代实现(GoogleChrome从版本25日Firefox版本23日以来,自528年WebKit版本的Safari和其他基于WebKit的浏览器)。这是目前唯一的头使用。
  • X-WebKit-CSP(弃用):实验头过去使用Chrome浏览器和其他基于webkit的浏览器。
  • X-Content-Security-Policy(弃用):实验头过去使用浏览器基于Gecko 2。

使用CSP指令

CSP允许您定义一个各种各样的内容限制使用指令,通常在HTTP响应头中指定。这里有一个例子CSP头文件添加到一个Apache web服务器:

标题设置Content-Security-Policy“default-src“自我”;“

添加到httpd . conf. htaccess文件,这将设置一个默认政策只允许内容从当前的起源(详情见下文)。

如果需要,您还可以提供特定的指令使用HTML meta标签在页面级别。这里有一个例子,上面的政策:

< meta http-equiv =“Content-Security-Policy”内容= " default-src自我”>

每个指令包含一个名称后面跟着一个或多个值,并以分号结束。您可以使用*通配符来匹配整体价值观,子域,计划,和港口:

Content-Security-Policy: default-src *: / / * .example.com

这个头将允许从任何子域名的来源example.com(但不example.com使用任何计划(本身)http,https等)。

官方的W3C推荐标准包含完整的指令列表与更正式的定义,但以下概述应该给你一个好主意最常用的。

源白名单的指令

CSP的主要目的是限制web内容源,所以有很多指令用于指定允许对各种类型的资产来源。一次Content-Security-Policy指定标题,浏览器将拒绝任何内容来源不明确白名单使用任何以下指令。源值由空间和可以包括url和特殊的关键字“没有”,“自我”,“unsafe-inline”,“unsafe-eval”(下面详细讨论)。注意,每个指令可以指定只有一次同样的标题,必须输入单引号和关键词。

  • default-src是一个回滚指令用来指定默认内容政策指令的来源。常见的用途包括default-src“自我”允许从当前内容(但不是它的子域)和起源default-src‘没有’阻止一切这不是显式地白名单。
  • script-src是用于指定脚本来源。只允许脚本从当前的起源,使用script-src“自我”
  • style-src使用白名单CSS样式表的来源。只允许样式表从当前的起源,使用style-src“自我”
  • connect-src指定允许的起源JavaScript直接连接使用EventSource,WebSocket,或XMLHttpRequest对象。
  • 对象src允许控制插件比如Flash的来源。请注意,您还可以指定允许插件类型使用plugin-typesv76指令(不支持在Firefox)。
  • img src允许您限制图像来源。
  • font-src指定允许加载字体来源。
  • media-src限制对加载声音和视频资源的起源。
  • child-src是用来限制允许JavaScript工人的url和嵌入式框架内容,包括嵌入式视频。在3级,frame-srcworker-src指令可以用来控制分别嵌入的内容和工作进程。
  • frame-ancestors限制可以嵌入当前资源的url< iframe >,<对象>和类似的元素。

编写JavaScript和CSS与CSP

内联代码是一个主要的注入向量,因为它总是在当前上下文执行,因此它不能被限制。当启用了CSP,默认所有内联代码块。这意味着没有内联样式或内联脚本,包括内联或事件处理程序javascript:url,所以任何新代码应该遵循最佳实践使用外部脚本和样式文件。的unsafe-inline关键字可以允许内联代码全部或部分脚本来源,但W3C建议避免在可能的情况下。

例如,一个老式的HTML和JavaScript页面可能包含在脚本代码<脚本>标签和内联事件处理程序:

< >脚本函数performButtonAction(){警报(“你点击按钮!”);}< /脚本> <按钮onclick = " performButtonAction(); " >想单击按钮吗?< /按钮>

重构现代和CSP-compliant风格,把一个单独的文件中的脚本,使用HTML纯粹的声明,所以类似:

< !- - - - - -- - - - - -buttonexample.html -->  

/ / buttonexample。js函数performButtonAction(){警报(“你点击按钮!”);}文档。addEventListener (DOMContentLoaded”内,函数(){. getelementbyid (examplebutton) .addEventListener(“点击”,performButtonAction);});

即使典型注射向量已被封堵,攻击者可能仍然实现脚本执行如果使用动态评估的代码。这也就是为什么CSP块字符串评估所有功能在默认情况下,包括eval (),新功能(),setTimeout ((字符串]),类似的结构。这个执行几个编码实践的变化,包括使用JSON.parse ()而不是eval ()解析JSON数据。

unsafe-inline类似,您可以使用unsafe-eval关键字允许代码评估部分或全部的起源。再一次,这是对现代代码的最佳实践,只能用于遗留代码无法重构。

目前和散列允许内联脚本

如果你绝对需要破例对一些遗留内联代码不能搬出去单独的文件,CSP提供了两种功能,允许特定的代码块不通过unsafe-inline。白名单一块特定的代码,您可以使用nonce(唯一一次性标识符)<脚本>标签或使用代码本身的密码散列。然后您可以指定特定场合或散列在你的script-src指令允许内联代码块。

根据定义,现时标志是一个“使用一次数量”,所以它必须为每个页面加载随机生成的。使用脚本nonce,指定它<脚本>标签使用现时标志并将其添加到属性script-src指令,前缀与价值现时标志- - - - - -。例如,您可能有一些遗留代码:

<脚本nonce = " uG2bsk6JIH923nsvp01n24KE " > alert('你好从Netsparker ');> < /脚本

允许这个特定的脚本标记,使用:

Content-Security-Policy: script-src nonce-uG2bsk6JIH923nsvp01n24KE”

重新生成nonce为每个页面加载可以麻烦,另一个方法是使用的密码散列允许代码本身。要做到这一点,首先计算沙散列内的所有字符<脚本>标签(但没有标签本身)。然后你就可以指定的散列值script-src指令,加前缀sha256 -,sha384 -,或sha512 -,这取决于所使用的算法。这里有相同的例子,但是没有现时标志属性:

<脚本> alert('你好从Netsparker '); > < /脚本

这段代码的指令使用SHA256散列将:

Content-Security-Policy: script-src sha256-db9763638d4e260082532ed81baf740fe3589b0920ce6039233435abfdbc9ef7”

页面级CSP指令

除了白名单内容源,CSP可以实施限制,当前页面可以采取的行动。要使用这个功能,使用沙盒指令将页面好像是在一个沙箱iframe。限制的完整描述执行的沙盒一个页面,看看沙盒HTML5规范。

提高安全性有很多遗留的老网站的HTTP页面,您可以使用upgrade-insecure-requests指令改写不安全的url。这指示用户代理改变HTTP, HTTPS URL方案和来说是无价的,当你还有多个HTTP URL。

测试策略和监控违规

内容安全策略控制内容源提供了强大的功能和页面的行为。然而,这也意味着一个配置错误的指令会使网站部分或完全无法访问的游客,所以您需要一种方法来安全地测试指令。

在你走之前生活的CSP指令,您可以使用Content-Security-Policy-Report-Only头,而不是Content-Security-Policy。在仅报告模式中,浏览器将监控政策和报告违规行为但没有实际执行的限制。使用report-uri指令,告诉浏览器它应该发布违反JSON格式的报告。这可以是任何地方或外部URI,例如:

Content-Security-Policy-Report-Only: default-src“自我”;…;report-uri / your_csp_report_parser;

注意,您可以结合Content-Security-Policy-Report-Only和Content-Security-Policy头来测试新政策同时执行现有的一个。

一旦生活的政策,您可以使用相同的report-uri指令违反有关政策的详细报告。每个JSON报告始于csp-report属性和看起来像这样:

{" csp-report ":{“文档uri”:“http://netsparker.com/index.html”,“推荐人”:“http://nasty.example.com/”,“blocked-uri”:“http://nasty.example.com/nasty.js”,“violated-directive”:“script-src”自我“https://apis.google.com”,“当初政策”:“script-src '自我' https://apis.google.com;report-uri http://netsparker.com/your_csp_report_parser "}}

正如您可以看到的,报告提供每个违反政策的信息,包括阻塞URI和违反指令。这使得故障诊断容易得多,尤其是对政策与数以百计的指令和价值观。

在Invicti内容安全政策支持

在过去的几年里,CSP二级已经实现在所有现代浏览器和广泛应用在网络作为一种有效的方法减少XSS的风险。为了反映这一点,Invicti检查的存在Content-Security-PolicyHTTP头信息和报告一个“最佳实践”漏洞如果他们失踪。

然而,仅仅在CSP头是不够的,无效的指令将被忽略的浏览器(因此无效),而不安全的指令值不会提供预期的保护级别。Invicti运行超过20详细检查,以确保指令使用正确语法结合值,提供有效的保障。看到脆弱性指数CSP的完整列表检查Invicti中可用。

演示内容的安全策略

最后,对于一个实际的演示配置CSP头,看这个安全周报采访Invicti安全研究员斯文Morgenroth。保罗•Asadoorian说话斯文了CSP旨在解决的问题,继续做CSP头的实际示例。

兹比格涅夫•巴拿赫

关于作者

兹比格涅夫•巴拿赫——管理编辑器和高级网络作家

网络作家和博客编辑总经理Invicti安全。凭借多年的经验与安全、软件开发、内容创作、新闻、和技术翻译,他尽自己最大的努力把web应用程序安全性和网络安全总体上更广泛的受众。

Baidu
map