如何让 KendoUI MVC 与内容安全策略一起工作
How can I get KendoUI MVC to work with Content Security Policy
如何在使用 ASP.NET MVC Kendo 组件时避免 Telerik KendoUI 创建内联脚本?
避免内联脚本的原因是为了遵守 CSP header
Content-Security-Policy: script-src 'self' 'unsafe-eval' https://kendo.cdn.telerik.com
并且不会出现像
这样的错误
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval' https://kendo.cdn.telerik.com".
有没有办法删除 kendo 生成的内联脚本或
将内容安全策略 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。
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"));
}
}
您可以控制 Kendo UI MVC 内联脚本在页面上的呈现位置,但不能完全删除它们。实际上,您可以,但是小部件将不会初始化。
考虑使用非 MVC Kendo UI 小部件:
http://docs.telerik.com/kendo-ui/aspnet-mvc/kendo-ui-vs-mvc-wrappers
Vanilla HTML/JavaScript Kendo UI widgets provide full control over the placement of the initialization scripts - server wrappers render the widgets' initialization scripts right after the widget's HTML output. Even if you use deferred initialization, the scripts are still kept in the View. When using plain (non-wrapper) Kendo UI widgets, you write the initialization scripts yourself and can move them to external script files.
还要记住KendoUI模板依赖eval
,如果启用CSP也会带来麻烦。
我尝试使用 Nuget (5.1.1 https://docs.nwebsec.com/en/aspnet4/index.html) 中的 NWebSec CSP 包,但无法使其与 Web.config 中的 NWebSec '<'content-Security-Policy> 部分一起使用.尽管 CSP 在 report-only 模式下看起来很好并且 Kendo 小部件工作,但一旦您打开 CSP,小部件就会完全失败。
我指出 '<'content-Security-Policy> section of the '<'nwebsec> in Web.config and moved all of my CSP directives back into '<'httpProtocol> <'customHeaders> 和 Kendo MVC (2018.1.322) 现在可以使用了。
通过将 NWebSec 作为项目的一部分进行维护并添加
@using NWebsec.Mvc.HttpHeaders.Csp 到视图中并将 HTMLHelper 应用到脚本标签中,我为任何内联脚本 '<'script @Html.CspScriptNonce() > 自动生成随机数,因此保留 NWebSec[=11 仍然很有价值=]
对于在 2019 年搜索此内容的任何人,我们将 Joonasw.AspNetCore.SecurityHeaders 用于我们的 Csp,它阻止了 kendo 使用的 eval(),我们通过将其添加到我们的 Startup
app.UseCsp(csp =>
{
...
csp.AllowScripts
.FromSelf()
.From("kendo.cdn.telerik.com")
.AllowUnsafeInline()
.AllowUnsafeEval();
...
}
如何在使用 ASP.NET MVC Kendo 组件时避免 Telerik KendoUI 创建内联脚本?
避免内联脚本的原因是为了遵守 CSP header
Content-Security-Policy: script-src 'self' 'unsafe-eval' https://kendo.cdn.telerik.com
并且不会出现像
这样的错误Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval' https://kendo.cdn.telerik.com".
有没有办法删除 kendo 生成的内联脚本或 将内容安全策略 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。
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"));
}
}
您可以控制 Kendo UI MVC 内联脚本在页面上的呈现位置,但不能完全删除它们。实际上,您可以,但是小部件将不会初始化。
考虑使用非 MVC Kendo UI 小部件:
http://docs.telerik.com/kendo-ui/aspnet-mvc/kendo-ui-vs-mvc-wrappers
Vanilla HTML/JavaScript Kendo UI widgets provide full control over the placement of the initialization scripts - server wrappers render the widgets' initialization scripts right after the widget's HTML output. Even if you use deferred initialization, the scripts are still kept in the View. When using plain (non-wrapper) Kendo UI widgets, you write the initialization scripts yourself and can move them to external script files.
还要记住KendoUI模板依赖eval
,如果启用CSP也会带来麻烦。
我尝试使用 Nuget (5.1.1 https://docs.nwebsec.com/en/aspnet4/index.html) 中的 NWebSec CSP 包,但无法使其与 Web.config 中的 NWebSec '<'content-Security-Policy> 部分一起使用.尽管 CSP 在 report-only 模式下看起来很好并且 Kendo 小部件工作,但一旦您打开 CSP,小部件就会完全失败。
我指出 '<'content-Security-Policy> section of the '<'nwebsec> in Web.config and moved all of my CSP directives back into '<'httpProtocol> <'customHeaders> 和 Kendo MVC (2018.1.322) 现在可以使用了。
通过将 NWebSec 作为项目的一部分进行维护并添加 @using NWebsec.Mvc.HttpHeaders.Csp 到视图中并将 HTMLHelper 应用到脚本标签中,我为任何内联脚本 '<'script @Html.CspScriptNonce() > 自动生成随机数,因此保留 NWebSec[=11 仍然很有价值=]
对于在 2019 年搜索此内容的任何人,我们将 Joonasw.AspNetCore.SecurityHeaders 用于我们的 Csp,它阻止了 kendo 使用的 eval(),我们通过将其添加到我们的 Startup
app.UseCsp(csp =>
{
...
csp.AllowScripts
.FromSelf()
.From("kendo.cdn.telerik.com")
.AllowUnsafeInline()
.AllowUnsafeEval();
...
}