/** * CVSS Calculator * Version 0.1 beta * Usage: * Create an HTML element with an id: *
* 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 } }