Security concerns

Version Date Notes By
0.1 2020-04-02 Initial release FPA

Cross-site scripting

Cross-site scripting (XSS) is a type of computer security vulnerability typically found in web applications. XSS attacks enable attackers to inject client-side scripts into web pages viewed by other users.
For more information about this security concern, please visit the dedicated page on OWASP.

Occurrence

A security audit verified that it was possible to perform an XSS attack on SGIV10, filling a form field with malicious content, like the one below:

<img src=1 href=1 onerror="javascript:alert(String.fromCharCode(86,117,108,110,101,114,225,118,101,108,33,32,67,111,110,115,101,103,117,105,32,103,117,97,114,100,97,114,32,101,115,116,97,32,115,99,114,105,112,116,32,110,97,32,66,68,46,32))"></img>

After that, when accessing the list of that resource, the script could be run automatically on the browser, opening an alert dialog with the content of the "attack".

Problem

The datatable's component on the list was filling some cells using the innerhtml binding, in order to be possible to display some styled content, but that content wasn't being sanitized.

Solution

To mitigate this problem it was created a value converter to sanitize the content we want to display, keeping some basic styling.

import DOMPurify from 'dompurify';

export class SanitizeHtmlValueConverter {
    /**
     * @param text
     * @param options
     *
     * @returns string
     */
    toView(text, options = {}) {
        return text ? DOMPurify.sanitize(text, options) : '';
    }
}

The DOMPurify package that we are using on this value converter is a third party plugin that does the real sanitization. For more information about this plugin, please visit it's Github page.

Prior to this we were inserting the content with something like this:

<div innerhtml.bind="row.data"></div>

Now, to sanitize the content of row.data and prevent XSS attacks, we must use the value converter and, the code will look something like this:

<div innerhtml.bind="row.data | sanitizeHtml"></div>