c# - 在外部 JavaScript 文件中插入动态值的安全方法

标签 c# javascript asp.net-mvc security content-security-policy

我正在实现 Content Security Policy使用以下策略的 header

Content-Security-Policy: default-src 'self'

因此需要避免内联脚本,因为它不会执行。

但是,在 MVC 应用程序中,某些功能(例如编辑器模板)使用内联脚本。例如tinymce_jquery_full.cshtml 包含

$(function() { 

    $('#@ViewData.TemplateInfo.GetFullHtmlFieldName(string.Empty)').tinymce({
...

使用 CSP 时,在外部 .js 文件中包含动态值的好方法是什么?

我目前的想法是两种方式之一:

C# 生成的 JavaScript

类似于JSONP的方式有效,除了在 URL 中我没有指定回调 - 我只是传递动态值。在每个需要动态 JavaScript 的文件中,我都包含一个链接,例如

<script src="/script/Foo/bar"></script>

点击 ScriptControllerFoo 操作返回类型为 text/javascript 的内容插入动态值 bar。这让我觉得这是一种可靠的方法,如果有点笨拙并且它首先会破坏使用 CSP 的一些优势(几乎与没有 CSP 时一样容易意外插入未编码的文本并导致 XSS) .

隐藏表单域

动态值被插入到页面中:

<input type="hidden" id="url" name="url" value"http:://www.example.com/" />

并在外部 JavaScript 文件中查找这些值:

$('#url').val();

这会起作用,但如果页面上有多个动态控件或者如果有多个相同类型的控件,它可能会很尴尬。问题是如何有效地将每个 .js 脚本与其隐藏字段匹配。

是否有更好的解决方案或是否有任何现成的框架可供我使用?

最佳答案

$('#@ViewData.TemplateInfo.GetFullHtmlFieldName(string.Empty)')

是的,这通常不是一个好方法。 Razor 默认情况下会进行 HTML 转义,但这里的上下文不仅仅是 HTML,它是:

  • 一个标识符,在里面
  • 一个 CSS 选择器,在里面
  • 内部的 JavaScript 字符串文字
  • 一个 JavaScript 语句,在里面
  • 一个 HTML CDATA 元素 ( <script> )

所以只是 HTML 转义是错误的——任何在选择器或 JS 字符串文字上下文中特殊的字符(例如点、反斜杠、撇号、行分隔符......)都会破坏这个声明。

假设 GetFullHtmlFieldName 的结果,也许这对于这个特定示例来说并不是特别重要总是安全的,但对于一般情况来说这不是一个好的假设。

C# Generated JavaScript: a bit clunky and it kind of defeats some of the advantages of using a CSP

同意,避免这种情况。获得正确的缓存并将信息从生成页面内容的 ASP 传输到生成脚本的页面通常很痛苦。

另外生成 JavaScript 也不一定那么简单。 ASP 和 Razor 模板不会为您提供自动 JS 转义器。 JSON 编码几乎可以做到这一点,除了 JSON 和 JS 之间的细微差别(即 U+2028 和 U+2029)。

Hidden Form Fields

更一般地说,将信息放在 DOM 中。隐藏表单域是一种方法。 data-属性是另一种常用的。无论哪种方式,我都非常喜欢 DOM 方法。

当使用隐藏的表单字段时,您应该删除 name属性就好像它们在真实的 <form> 中一样您通常实际上并不想将传递给 JS 的数据提交。

这样您就可以使用正常的默认 HTML 转义将内容注入(inject)到模板中。如果您需要更多结构,您始终可以对要传递的数据进行 JSON 编码。 jQuery 的 data()助手会自动 JSON.parse在那种情况下,它们也适合你。

<body data-mcefields="@Json.Encode(GetListOfHtmlFields())">
...
var mce_array = $('body').data('mcefields');
$.each(mce_array, function() {
    var element = document.getElementById(this);
    $(element).tinymce({ ... });
});

(虽然...对于选择要应用 HTML 编辑器的元素的特定情况,也许更简单的方法只是使用 class="tinymce" 并应用 $('.tinymce').tinymce(...) ?)

关于c# - 在外部 JavaScript 文件中插入动态值的安全方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21428259/

相关文章:

c# - 即使在使用 if 语句检查后,字符串也不包含字符

javascript - 1 个 div 中有 2 个鼠标悬停/悬停效果?

javascript - 使用c3 js,有没有办法在放大时显示更多的x轴值?

javascript - 无法让 phonegap device.platform 工作

c# - 从 WebApi 返回 JsonResult 不工作 ASP.NET

asp.net - 在操作之外执行异步操作 asp.net mvc

asp.net-mvc - 使用 TextBoxFor 设置具有命名空间前缀的 HTML 属性

c# - 我如何反射(reflect)动态对象的成员?

c# - UWP 透明 LinearGradientBrush

c# - 在 MVC 中向我的编辑 Controller 添加删除功能