summaryrefslogtreecommitdiffstats
path: root/web/gui/src/dashboard.js/xss.js
blob: fa66f34dacd38362206cee3c09d6cc9c9c215462 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// ----------------------------------------------------------------------------------------------------------------
// XSS checks

NETDATA.xss = {
    enabled: (typeof netdataCheckXSS === 'undefined') ? false : netdataCheckXSS,
    enabled_for_data: (typeof netdataCheckXSS === 'undefined') ? false : netdataCheckXSS,

    string: function (s) {
        return s.toString()
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;');
    },

    object: function (name, obj, ignore_regex) {
        if (typeof ignore_regex !== 'undefined' && ignore_regex.test(name)) {
            // console.log('XSS: ignoring "' + name + '"');
            return obj;
        }

        switch (typeof(obj)) {
            case 'string':
                const ret = this.string(obj);
                if (ret !== obj) {
                    console.log('XSS protection changed string ' + name + ' from "' + obj + '" to "' + ret + '"');
                }
                return ret;

            case 'object':
                if (obj === null) {
                    return obj;
                }

                if (Array.isArray(obj)) {
                    // console.log('checking array "' + name + '"');

                    let len = obj.length;
                    while (len--) {
                        obj[len] = this.object(name + '[' + len + ']', obj[len], ignore_regex);
                    }
                } else {
                    // console.log('checking object "' + name + '"');

                    for (var i in obj) {
                        if (obj.hasOwnProperty(i) === false) {
                            continue;
                        }
                        if (this.string(i) !== i) {
                            console.log('XSS protection removed invalid object member "' + name + '.' + i + '"');
                            delete obj[i];
                        } else {
                            obj[i] = this.object(name + '.' + i, obj[i], ignore_regex);
                        }
                    }
                }
                return obj;

            default:
                return obj;
        }
    },

    checkOptional: function (name, obj, ignore_regex) {
        if (this.enabled) {
            //console.log('XSS: checking optional "' + name + '"...');
            return this.object(name, obj, ignore_regex);
        }
        return obj;
    },

    checkAlways: function (name, obj, ignore_regex) {
        //console.log('XSS: checking always "' + name + '"...');
        return this.object(name, obj, ignore_regex);
    },

    checkData: function (name, obj, ignore_regex) {
        if (this.enabled_for_data) {
            //console.log('XSS: checking data "' + name + '"...');
            return this.object(name, obj, ignore_regex);
        }
        return obj;
    }
};