Knockout: CSP compliancy

Created on 28 Mar 2013  路  14Comments  路  Source: knockout/knockout

I don't really know if this is something workable or not: using KO with the new Chrome apps (and I think some other environment too) require to use a sandbox page which doesn't have access to all the powerful chrome specific apis because it uses new Function I think for the execution of template code.

It would be possible to give an option to disable the usage of this? I mean the context of data-bind could be parsed in some other way, we would lost the ability to use inline javascript in data-bind but that, I think, is only a good thing because using inline javascript is not exactly the best practice.

Most helpful comment

I am just summarizing, since CSP represents a substantial improvement in client-side web security. Script injection is a legitimate concern and it would be a shame if one could not use knockout along with CSP restrictions.

Just for clarification, the CSP restriction at issue with Knockout is script-src, which by default prevents eval, new Function, setTimeout(string) and setInterval(string). Basically it prohibits converting from string to script.

The problem for Knockout is that new Function is called in createBindingsStringEvaluator.

As Steve points out, it would be challenging to implement a parser for data-bind without the native
Javascript interpreter. The alternative might be to include something like esprima. That'd be madness.

Practical workarounds may be:

  1. disabling the CSP script-src restriction by adding 'unsafe-eval';
  2. using an alternative data binding e.g. the class binding by @rniemeyer .

Disabling 'unsafe evaluations' practically neuters the CSP, since one of the most valuable protections CSP provides is against script injection.

It seems reasonable to conclude that an alternative data binding will for the foreseeable future be the only practical solution.

Perhaps in future, with CSP 1.1 and beyond, restrictions may become more granular and another alternative may crop up. For example, I read discussions about a new SafeFunction (I'm making that name up) that is CSP safe but has restrictions built in e.g. no DOM access.

I think it would be worthwhile to note Knockout's relationship to CSP in the documentation at some point - since I am sure this inquiry will only get more popular over time.

All 14 comments

Is it only a problem if a new Function or eval call is actually made?

If so, then you can easily use a custom binding provider like the one here.

I'm not sure it's realistic to implement an entire JavaScript parser/evaluator without using eval or new Function, so as Paglias points out, we would lose the ability to evaluate custom expressions in bindings. Since custom expressions in bindings is one of the most useful features in KO, I don't think we'd want to lose that from the core library!

I'll close this as I don't think it's a realistic direction for KO to go in, but I'd second Ryan's suggestion of trying out a custom binding provider if you really do want a limited version of KO that can comply with this restriction.

Angular has some movement in this derection http://docs.angularjs.org/api/ng.directive:ngCsp

Hi,
I'm currently implementing an app for Firefox OS where CSP compliance is a requirement for privileged apps. (https://developer.mozilla.org/en-US/Apps/Developing/Packaged_apps)

It would be great to have it.

@puzrin, Angular has a much more limited expression syntax than Knockout; Knockout allows any valid Javascript. So, as @rniemeyer pointed out, the only way to support this in Knockout is with a custom binding provider.

@mbest, i think, it would be nice to add docs on situation with csp. I guess, it's not the first and not the last ticket about :) . Also, probably, it would we useful to have limited expression syntax for csp, because doing custom bindings providers everywhere looks overcomplicated.

Just my opinion.

Someone who's interested in this and has the necessary skills should publish a CSP binding provider plugin that anyone can use.

@mbest, I think, that https://github.com/rniemeyer/knockout-classBindingProvider by @rniemeyer - is good solution (or "processor", which will convert all "data-bind" => "data-class" + binding)

I am just summarizing, since CSP represents a substantial improvement in client-side web security. Script injection is a legitimate concern and it would be a shame if one could not use knockout along with CSP restrictions.

Just for clarification, the CSP restriction at issue with Knockout is script-src, which by default prevents eval, new Function, setTimeout(string) and setInterval(string). Basically it prohibits converting from string to script.

The problem for Knockout is that new Function is called in createBindingsStringEvaluator.

As Steve points out, it would be challenging to implement a parser for data-bind without the native
Javascript interpreter. The alternative might be to include something like esprima. That'd be madness.

Practical workarounds may be:

  1. disabling the CSP script-src restriction by adding 'unsafe-eval';
  2. using an alternative data binding e.g. the class binding by @rniemeyer .

Disabling 'unsafe evaluations' practically neuters the CSP, since one of the most valuable protections CSP provides is against script injection.

It seems reasonable to conclude that an alternative data binding will for the foreseeable future be the only practical solution.

Perhaps in future, with CSP 1.1 and beyond, restrictions may become more granular and another alternative may crop up. For example, I read discussions about a new SafeFunction (I'm making that name up) that is CSP safe but has restrictions built in e.g. no DOM access.

I think it would be worthwhile to note Knockout's relationship to CSP in the documentation at some point - since I am sure this inquiry will only get more popular over time.

Further to my summary above, I have written a custom binding provider that I call Knockout Secure Binding that offers a drop-in replacement for knockout data-bind called data-sbind. However instead of using new Function, data-sbind parses the bindings, the old JSON way.

Of course the data-sbind language is a subset of Javascript, but since we are using a parser we do have some flexibility to extend it. There is nothing limiting us to Javascript though we would probably be wise to stay there.

I would be sincerely grateful for any thoughts and comments. This being freshly minted I can imagine there being some issues and kinks to work out.

Link: The Knockout Secure Binding Github page.

@brianmhunt, thanks for putting that together. I'm sure it will be useful for many people.

Is there any plan to support CSP out of the box in future versions of Knockout JS?
@mbest @rniemeyer

Any updates on this issue?

TKO, in alpha now, supports CSP out of the box.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

priyank-eschool picture priyank-eschool  路  7Comments

andersekdahl picture andersekdahl  路  6Comments

johnpapa picture johnpapa  路  9Comments

nkosi23 picture nkosi23  路  5Comments

IPWright83 picture IPWright83  路  7Comments