File size: 4,360 Bytes
6440a30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
 * CVSS Calculator
 * Version 0.1 beta
 * Usage:
 *     Create an HTML element with an id:
 *     <div id="cvssboard"></div>
 *     Instantiate the CVSS calculator:
 *     let c = new CVSS("cvssboard");
 *     or with optional callbacks:
 *     let c = new CVSS("cvssboard", {
 *         onchange: function() {...},
 *         onsubmit: function() {...}
 *     });
 * 
 *     Set a vector:
 *     c.set('AV:L/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:L');
 *     Retrieve the result:
 *     c.get() -> { score: 4.3, vector: 'AV:L/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:L' }
 */

// CVSS Class
class CVSS {
    constructor(id, options = {}) {
        this.options = options;
        this.containerId = id;
        this.container = document.getElementById(id);
        this.baseMetrics = this.getBaseMetrics();
        this.metricElements = {};
        this.setupUI();
    }

    getBaseMetrics() {
        return {
            AV: { label: 'Attack Vector', values: { N: 'Network', A: 'Adjacent', L: 'Local', P: 'Physical' }},
            AC: { label: 'Attack Complexity', values: { L: 'Low', H: 'High' }},
            PR: { label: 'Privileges Required', values: { N: 'None', L: 'Low', H: 'High' }},
            UI: { label: 'User Interaction', values: { N: 'None', R: 'Required' }},
            S:  { label: 'Scope', values: { C: 'Changed', U: 'Unchanged' }},
            C:  { label: 'Confidentiality', values: { H: 'High', L: 'Low', N: 'None' }},
            I:  { label: 'Integrity', values: { H: 'High', L: 'Low', N: 'None' }},
            A:  { label: 'Availability', values: { H: 'High', L: 'Low', N: 'None' }}
        };
    }

    setupUI() {
        if (!this.container) return;
        
        const form = document.createElement('form');
        form.className = 'cvss-form';

        for (let metric in this.baseMetrics) {
            const metricData = this.baseMetrics[metric];
            const dl = document.createElement('dl');
            dl.className = metric;

            const dt = document.createElement('dt');
            dt.textContent = metricData.label;
            dl.appendChild(dt);

            for (let value in metricData.values) {
                const dd = document.createElement('dd');
                dl.appendChild(dd);

                const input = document.createElement('input');
                input.type = 'radio';
                input.name = metric;
                input.value = value;
                input.id = `${this.containerId}-${metric}-${value}`;
                input.className = `${metric}-${value}`;
                input.addEventListener('change', () => this.updateMetric(metric, value));

                this.metricElements[`${metric}-${value}`] = input;
                dd.appendChild(input);

                const label = document.createElement('label');
                label.setAttribute('for', input.id);
                label.textContent = metricData.values[value];
                dd.appendChild(label);
            }
            form.appendChild(dl);
        }

        this.container.appendChild(form);
        this.form = form;
    }

    updateMetric(metric, value) {
        // You can implement the metric change logic here if needed
        console.log(`Metric ${metric} changed to ${value}`);
        if (this.options.onchange) this.options.onchange();
    }

    set(vector) {
        const metrics = vector.split('/');
        metrics.forEach(pair => {
            const [metric, value] = pair.split(':');
            if (this.metricElements[`${metric}-${value}`]) {
                this.metricElements[`${metric}-${value}`].checked = true;
            }
        });
    }

    get() {
        const result = { score: 0, vector: [] };
        for (let metric in this.baseMetrics) {
            const checkedInput = this.form.querySelector(`input[name=${metric}]:checked`);
            if (checkedInput) {
                result.vector.push(`${metric}:${checkedInput.value}`);
            }
        }
        result.vector = result.vector.join('/');
        // Calculations for the score would go here. This is just a placeholder.
        result.score = this.calculateScore(result.vector);
        return result;
    }

    calculateScore(vector) {
        // Placeholder scoring function; implement CVSS scoring here if needed
        return Math.random() * 10; // Example score calculation
    }
}