内联JavaScript与CSP级别1结合使用

内联JavaScript与CSP级别1结合使用,javascript,json,http,inline,content-security-policy,Javascript,Json,Http,Inline,Content Security Policy,关于使用内联JavaScript的思考 我们的开发团队正在进行一个新的网络相关项目。在该项目中,安全性具有非常高的优先级。然而,在浏览器支持方面实施内容安全策略(CSP)却变得既痛苦又麻烦 众所周知,引入CSP是为了通过阻止所有外部CSS/JavaScript文件和阻止执行内联脚本来减轻XSS注入。指令允许我们定义浏览器将执行的内容和源的白名单(例如“自我”、域、协议等) 然而,执行内联JavaScript代码是一个完全不同的故事。CSP允许使用“不安全内联”指令执行内联代码。然而,添加此指令违

关于使用内联JavaScript的思考

我们的开发团队正在进行一个新的网络相关项目。在该项目中,安全性具有非常高的优先级。然而,在浏览器支持方面实施内容安全策略(CSP)却变得既痛苦又麻烦

众所周知,引入CSP是为了通过阻止所有外部CSS/JavaScript文件和阻止执行内联脚本来减轻XSS注入。指令允许我们定义浏览器将执行的内容和源的白名单(例如“自我”、域、协议等)

然而,执行内联JavaScript代码是一个完全不同的故事。CSP允许使用“不安全内联”指令执行内联代码。然而,添加此指令违背了实施CSP的目的

为了克服这一障碍,我们的团队花了一些时间讨论可行的解决方案。 在以下段落中,我们将讨论一些解决方案。欢迎对这些解决方案提出任何建议和反馈

提案#1:外部文件

在外部文件中提供特定于页面的代码。该文件将在每次请求时生成,因为它包含动态数据(例如Google Maps密钥、GA跟踪片段、php调试栏)。 下面的习惯用法说明了如何在HTML代码中实现此建议

<html>
    <head>
        <script src="/generated/external-file.js"></script>
    </head>
</html>
出于安全原因,此nonce必须是随机的,并且必须在每次请求时重新生成

优点:由CSP的2级支持

缺点:浏览器支持是一个问题(75%的浏览器实施CSP 2级,日期为2017年4月10日()

提案#3:结合CSP进行哈希运算

CSP的级别2通过散列这些元素的内容并在CSP响应头中提供此散列来支持内联样式和脚本。 以下习惯用法说明了一个内联脚本,其内容将生成以下SHA-256哈希:9E8A3B5E27971B7309FF6C00F5C80644FFE68E635CE797D7EED8EE23D485A19F2

<script>console.log('Hello world');</script>
优点:受CSP第2级支持,允许通过使用HTTP加速器缓存页面

缺点:浏览器支持是一个问题(75%的浏览器实施CSP 2级,日期为2017年4月10日()

提案#4:JSON

CSP仅禁止包含可执行JavaScript代码的脚本元素,简而言之,这意味着允许在脚本元素中使用配置数据。 下面的习惯用法演示了包含JSON数据的脚本元素

<script type="application/json">
{
    "googleMapsKey": "v1zs9Bc10hMZ073S14gy",
    "analyticsProperty": "UA-192348"
}
</script>
优点:支持CSP级别1,并且在大多数浏览器支持CSP级别2的情况下,可以调整为提案2而无需太多麻烦

缺点:必须经过彻底测试的自定义实现,需要CSP标题中的“不安全评估”指令


请分享您的想法,我们将感谢您的反馈!

内容安全策略可以逐页定义:您可以根据特定页面的特定需求微调策略

外部文件

与其试图找到一个解决方案来解决所有问题,我建议从将所有“非动态”内联样式和脚本移动到外部文件开始。内容安全策略的存在是因为内联脚本不总是可信的。使用外部文件除了与CSP配合良好外,还有许多优点:

  • 浏览器更容易缓存外部资源
  • 开发商更容易理解
  • 有利于编制和缩小
沙箱

另一个值得一看的“解决方案”是沙盒。如果存在
sandbox
指令,则该页面将被视为加载在具有
沙盒
属性的

有关沙箱的更多信息,请访问:

更多信息

谷歌开发者指南:

Mozilla开发者指南:


W3C的Web应用程序安全工作组已经开始了规范下一次迭代的工作。

对于
提案#4 JSON
,为什么它不能为每个请求存储
动态生成的JavaScript代码
?您可以将动态内容从HTTP响应变量传递到呈现模板要由外部JavaScript评估的“生成的”JavaScript仍然存在安全风险。无法验证提供的JSON是否已被XSS攻击修改(或在新元素中由提供),因此攻击者仍然能够注入由外部JavaScript处理的易受攻击的代码。大多数静态JavaScript代码都是从外部加载的。但某些JavaScript片段无法从外部加载,例如:在将访问者分配到具有分析功能的a/B测试时,发送页面事件(定义的后端),一次性跟踪转换,等等。我还没有看一看
sandbox
指令,值得一看!
<script>console.log('Hello world');</script>
Content-Security-Policy: script-src 'sha256-9e8a3b5e27971b7309ff6c00f5c80644ffe8e635ce797d7eed8ee23d485a19f2;'
<script type="application/json">
{
    "googleMapsKey": "v1zs9Bc10hMZ073S14gy",
    "analyticsProperty": "UA-192348"
}
</script>
Content-Security-Policy: script-src 'unsafe-eval'