How to find XSS in Knockout.js Applications

Knockout is an easy to use Javascript MVC framework. Honestly it is one of my favorite to work with. I find the barrier to entry to be minimal and it still packs quite a punch in functionality.

Knockout works by making use of the data-bind HTML tag attribute and replaces the contents of the tag programmatically.

Below is a classic example of Knockout.js

<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
<h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
// Here's my data model
var ViewModel = function(first, last) {
    this.firstName = ko.observable(first);
    this.lastName = ko.observable(last);

    this.fullName = ko.computed(function() {
        // Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName,
        // because these get called when evaluating fullName.
        return this.firstName() + " " + this.lastName();
    }, this);
};

ko.applyBindings(new ViewModel("Planet", "Earth"));

This code is not vulnerable to XSS because the text element is being set.

<h2>Hello, <span data-bind="text: fullName"> </span>!</h2>

Were this to be written as

<h2>Hello, <span data-bind="html: fullName"> </span>!</h2>

It will be vulnerable. This is because data-bind="html:" modifies the element.innerHTML attribute if the tag allowing for HTML to be placed into the DOM. This HTML will be evaluated and executed.

Here is a list of Knockout.js features that may be used as an XSS vector in your application.

  • data-bind will execute any statement that it is given. Here is some sample template code written that is vulnerable XSS.
<p>First name: <input data-bind="text: firstName-{{ user_defined_var }}" /></p>

Even if the user controlled variable is within a comment, Knockout.JS parses comments and will execute them if they start with <!-- ko ... -->

<!-- ko if: {{ user_control_var }} -->
<!-- /ko -->
  • Adding user controlled data into the following data-bind elements may make you susceptible to XSS
    1. html
    2. css
    3. style
    4. attr