Secure way of inserting dynamic values in external JavaScript files

大憨熊 提交于 2019-11-28 00:58:55

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

Yeah this isn't a good approach in general. Razor will HTML-escape by default but the context isn't simply HTML here, it's:

  • an identifier, inside
  • a CSS selector, inside
  • a JavaScript string literal, inside
  • a JavaScript statement, inside
  • an HTML CDATA element (<script>)

so just HTML-escaping is the wrong thing - any characters that are special in the context of selectors or JS string literals (such as dot, backslash, apostrophe, line separators...) would break this statement.

Maybe that's not super-important for this specific example, assuming the result of GetFullHtmlFieldName is always going to be something safe, but that's not a good assumption for the general case.

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

Agreed, avoid this. Getting the caching right and transferring the information from the ASP that generates the page content to the page that generates the script is typically a pain.

Also generating JavaScript is not necessarily that simple. ASP and Razor templates don't give you an automatic JS escaper. JSON encoding nearly does it, except for the niggling differences between JSON and JS (ie U+2028 and U+2029).

Hidden Form Fields

More generally, putting the information in the DOM. Hidden form fields are one way to do this; data- attributes are another commonly-used one. Either way I strongly prefer the DOM approach.

When using hidden form fields you should probably remove the name attribute as if they're inside a real <form> you typically don't actually want to submit the data you were passing into JS.

This way you can inject the content into the template using normal default-on HTML escaping. If you need more structure you can always JSON-encode the data to be passed. jQuery's data() helper will automatically JSON.parse them for you too in that case.

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

(Although... for the specific case of selecting elements to apply an HTML editor to, perhaps the simpler way would be just to use class="tinymce" and apply with $('.tinymce').tinymce(...)?)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!