【问题标题】:How can I get KendoUI MVC to work with Content Security Policy如何让 KendoUI MVC 使用内容安全策略
【发布时间】:2016-12-31 17:34:57
【问题描述】:

如何避免 Telerik KendoUI 在使用 ASP.NET MVC Kendo 组件时创建内联脚本?

避免内联脚本的原因是为了遵守 CSP 标头

Content-Security-Policy: script-src 'self' 'unsafe-eval' https://kendo.cdn.telerik.com

而且不会出现类似的错误

拒绝执行内联脚本,因为它违反了以下内容安全策略指令:“script-src 'self' 'unsafe-eval' https://kendo.cdn.telerik.com”。

有没有办法删除剑道生成的内联脚本或 将内容安全策略 nonce / sha256 附加到脚本?

简单示例(KendoUI 菜单)

cshtml

@(Html.Kendo().Menu()
  .Name("nav-menu")
  .Items(items =>
  {
      items.Add().Text("Home").Action("Index", "Overview");
  })
)

浏览器html

<ul class="k-widget k-reset k-header k-menu k-menu-horizontal" id="nav-menu" data-role="menu" tabindex="0" role="menubar" aria-activedescendant="nav-menu_mn_active">
    <li class="k-item k-state-highlight k-state-default k-first" role="menuitem">
        <a class="k-link" href="/">Home</a>        
    </li>
</ul>
<script>
    jQuery(function(){jQuery("#nav-menu").kendoMenu({});});
</script>

解决方案

在@dimodi 的回答之后,我最终在 kendo 延迟初始化脚本上使用了 nonce。

来源:CSP Nonces in ASP.NET

cshtml

@(Html.Kendo().Menu()
  .Name("nav-menu")
  .Items(items =>
  {
      items.Add().Text("Home").Action("Index", "Overview");
  })
  .Deferred()
)

<script type="text/javascript" nonce="@Html.ScriptNonce()">
    @Html.Kendo().DeferredScripts(false)
</script>

Startup.cs

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.Use((context, next) =>
        {
            var rng = new RNGCryptoServiceProvider();
            var nonceBytes = new byte[32];
            rng.GetBytes(nonceBytes);
            var nonce = Convert.ToBase64String(nonceBytes);
            context.Set("ScriptNonce", nonce);
            context.Response.Headers.Add("Content-Security-Policy",
                new[] {$"script-src 'self' 'unsafe-eval' https://kendo.cdn.telerik.com 'nonce-{nonce}';"
            });
            return next();
        });
    }
}

public static class NonceHelper
{
    public static IHtmlString ScriptNonce(this HtmlHelper helper)
    {
        var owinContext = helper.ViewContext.HttpContext.GetOwinContext();
        return new HtmlString(owinContext.Get<string>("ScriptNonce"));
    }
}

【问题讨论】:

    标签: javascript asp.net-mvc kendo-ui telerik content-security-policy


    【解决方案1】:

    您可以控制 Kendo UI MVC 内联脚本在页面上的呈现位置,但不能完全删除它们。其实可以,但是小部件不会初始化。

    考虑使用非 MVC Kendo UI 小部件:

    http://docs.telerik.com/kendo-ui/aspnet-mvc/kendo-ui-vs-mvc-wrappers

    Vanilla HTML/JavaScript Kendo UI 小部件提供对初始化脚本位置的完全控制 - 服务器包装器在小部件的 HTML 输出之后立即呈现小部件的初始化脚本。即使您使用deferred initialization,脚本仍然保留在视图中。使用普通(非包装)Kendo UI 小部件时,您可以自己编写初始化脚本,并且可以将它们移动到外部脚本文件中。

    还要记住,Kendo UI 模板依赖于eval,如果启用 CSP 也会带来麻烦。

    【讨论】:

      【解决方案2】:

      我尝试使用来自 Nuget (5.1.1 https://docs.nwebsec.com/en/aspnet4/index.html) 的 NWebSec CSP 包,但无法使其与 Web.config 中的 NWebSec ' 部分一起使用。尽管 CSP 在仅报告模式下看起来很好,并且 Kendo 小部件可以工作,但只要您打开 CSP,小部件就会完全失效。

      我在 Web.config 中注释掉了 ' 的 ' 部分,并将我的所有 CSP 指令移回了 ' 和 Kendo MVC( 2018.1.322) 现在可以工作了。

      通过维护 NWebSec 作为项目的一部分并添加 @使用 NWebsec.Mvc.HttpHeaders.Csp 到视图中并将 HTMLHelper 应用到脚本标签中我会为任何内联脚本自动生成随机数 ' 所以保留 NWebSec 仍然很有价值

      【讨论】:

        【解决方案3】:

        对于在 2019 年搜索此内容的任何人,我们将 Joonasw.AspNetCore.SecurityHeaders 用于我们的 Csp,它阻止了 kendo 使用的 eval(),我们通过将其添加到我们的 Startup 来解决这个问题

        app.UseCsp(csp =>
                    {
                         ...
                           csp.AllowScripts
                        .FromSelf()
                        .From("kendo.cdn.telerik.com")
                        .AllowUnsafeInline()
                        .AllowUnsafeEval();
        
                         ...
                     }
        

        【讨论】:

          猜你喜欢
          • 2020-06-14
          • 1970-01-01
          • 1970-01-01
          • 2017-09-07
          • 2016-06-22
          • 2020-01-25
          • 2015-04-27
          • 1970-01-01
          • 2021-10-13
          相关资源
          最近更新 更多