dradis-calculator_cvss 5.1.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a1a2072b667c860a4b3fd935ab8fb241f6c36a0650572ded51717a2787942c7
4
- data.tar.gz: f39277db07d072d179b1951c97d32ffc2c8f2e4ddf527156213ace741ee20fc8
3
+ metadata.gz: 6ddfa19b5e944d64fd26441b4c5cab892c1ab699fce18d15deca214716317642
4
+ data.tar.gz: 8ba4fd687f8b337aea206a224c8123376801c4d9c111566da43a7a86152531b7
5
5
  SHA512:
6
- metadata.gz: 95956efbf3a2a1fe8552c7695641700ce136d9b16acbc911f8f515ca1d5b6d8b3141ca9527255c602da85027efdce716a9ad97b6c4dc46e392378de3aa3ccb9a
7
- data.tar.gz: 89c187a8dc111632c4458d362f7c9e3e975fe2d782f00410530bfbca6c96935a79a221a2775ab28d127aab67b282f1d054715fc2eee86808e02f92249f6ceb9f
6
+ metadata.gz: 013340f2cd3d244c113bf08e34d2f2c59fbdfaa185f59822d7f5377f1cdc9a8900ff4bbfe0ed0acabc83c8c33c9c3601d475d397ef7683e18cc19316a93c4fb4
7
+ data.tar.gz: ed38184af176f4ddff322fae7378110009098ba0a045021a59b7710fbfd78ea9ac4822d2f0db9c793cc6753a59bd65eeb0a029f4e67b2421ff7aee56a6e25d53
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ v5.2.0 (July 2026)
2
+ - Standalone calculator: redesign with two-column layout, sticky results panel, severity badges, and vector string copy
3
+
1
4
  v5.1.0 (May 2026)
2
5
  - No changes
3
6
 
data/README.md CHANGED
@@ -1,10 +1,12 @@
1
1
  # CVSS score calculator for Dradis
2
2
 
3
- This simple add-on adds a new page under `/calculators/cvss` for you to perform CVSS score calculations:
3
+ This add-on adds the Common Vulnerability Scoring System (CVSS) risk calculator to [Dradis Framework](https://dradis.com/):
4
4
 
5
5
  ![cvss4_calculator](https://github.com/dradis/dradis-calculator_cvss/assets/111541062/fd957a70-c068-4453-908e-be50beff9325)
6
6
 
7
- The Common Vulnerability Scoring System (CVSS) Version 4.0, 3.1, 3.0 Calculator is heavily inspired in the one provided by [FIRST](https://www.first.org/cvss/calculator/3.0).
7
+ Versions 4.0, 3.1, 3.0 of CVSS are supported in the calculator, which is heavily inspired in the one provided by [FIRST](https://www.first.org/cvss/calculator/3.0).
8
+
9
+ You can try the [CVSS calculator online](https://dradis.com/tools/calculators/cvss.html) and outside of Dradis.
8
10
 
9
11
 
10
12
  ## Install
@@ -1,32 +1,57 @@
1
- $(document).on('turbo:load', function () {
2
- if ($('[data-behavior~=cvss-version]').length) {
3
- function handleVersionSelection() {
4
- var selectedValue = $('[data-behavior~=cvss-version]').val();
5
- $('[data-cvss-version]').addClass('d-none');
6
- switch (selectedValue) {
7
- case '40':
8
- $('[data-cvss-version=4]').removeClass('d-none');
9
- window.calculator = new CVSS40Calculator();
10
- break;
11
- case '31':
12
- $('[data-cvss-version=3]').removeClass('d-none');
13
- window.calculator = new CVSS31Calculator();
14
- break;
15
- case '30':
16
- $('[data-cvss-version=3]').removeClass('d-none');
17
- window.calculator = new CVSS30Calculator();
18
- break;
19
- }
1
+ $(document).on('turbo:load', () => {
2
+ if (!$('[data-behavior~=cvss-version]').length) return;
3
+
4
+ const isStandalone = $('[data-behavior~=cvss-calculator]').length > 0;
5
+
6
+ const handleVersionSelection = () => {
7
+ const selectedValue = $('[data-behavior~=cvss-version]').val();
8
+ $('[data-cvss-version]').addClass('d-none');
9
+
10
+ switch (selectedValue) {
11
+ case '40':
12
+ $('[data-cvss-version=4]').removeClass('d-none');
13
+ window.calculator = new CVSS40Calculator();
14
+ break;
15
+ case '31':
16
+ $('[data-cvss-version=3]').removeClass('d-none');
17
+ window.calculator = new CVSS31Calculator();
18
+ break;
19
+ case '30':
20
+ $('[data-cvss-version=3]').removeClass('d-none');
21
+ window.calculator = new CVSS30Calculator();
22
+ break;
20
23
  }
21
- handleVersionSelection();
22
- $('[data-behavior~=cvss-error]').addClass('d-none');
23
- $('[data-behavior~=cvss-buttons] button').on('click', function () {
24
- var $this = $(this);
25
- $this.parent().find('button').removeClass('active btn-primary');
26
- $this.addClass('active btn-primary');
27
- $(`input[name="${$this.attr('name')}"]`).val($this.val());
28
- window.calculator.calculate();
29
- });
30
- $('[data-behavior~=cvss-version]').on('change', handleVersionSelection);
31
- }
24
+ };
25
+
26
+ handleVersionSelection();
27
+ $('[data-behavior~=cvss-error]').addClass('d-none');
28
+
29
+ $('[data-behavior~=cvss-buttons] button').on('click', function () {
30
+ const $btn = $(this);
31
+ const $siblings = $btn.parent().find('button');
32
+
33
+ $siblings.removeClass('active btn-primary');
34
+
35
+ if (isStandalone) {
36
+ $siblings.addClass('btn-outline-primary');
37
+ $btn.removeClass('btn-outline-primary');
38
+ }
39
+
40
+ $btn.addClass('active btn-primary');
41
+ $(`input[name="${$btn.attr('name')}"]`).val($btn.val());
42
+ window.calculator.calculate();
43
+ });
44
+
45
+ $('[data-behavior~=cvss-version]').on('change', handleVersionSelection);
46
+
47
+ $('[data-behavior~=cvss-copy-vector]').on('click', function () {
48
+ const vectorText = $('[data-behavior~=cvss4-vector]').text();
49
+ navigator.clipboard.writeText(vectorText);
50
+
51
+ const $btn = $(this);
52
+ $btn.find('i').removeClass('fa-regular fa-copy').addClass('fa-solid fa-check');
53
+ setTimeout(() => {
54
+ $btn.find('i').removeClass('fa-solid fa-check').addClass('fa-regular fa-copy');
55
+ }, 2000);
56
+ });
32
57
  });
@@ -209,8 +209,19 @@ class CVSS40Calculator extends CVSS4Calculator {
209
209
  }
210
210
 
211
211
  $('[data-behavior=cvss4-result-text] textarea').val(issue_cvss);
212
- $('[data-behavior=cvss4-result]').html(
213
- this.app.score() + ' (' + this.app.qualScore() + ')',
214
- );
212
+
213
+ const score = this.app.score();
214
+ const severity = this.app.qualScore();
215
+
216
+ if ($('[data-behavior=cvss4-severity]').length) {
217
+ $('[data-behavior=cvss4-result]').text(score);
218
+ $('[data-behavior=cvss4-severity]')
219
+ .text(severity)
220
+ .removeClass('cvss-severity-none cvss-severity-low cvss-severity-medium cvss-severity-high cvss-severity-critical')
221
+ .addClass(`cvss-severity-${severity.toLowerCase()}`);
222
+ $('[data-behavior=cvss4-vector]').text(this.baseVector());
223
+ } else {
224
+ $('[data-behavior=cvss4-result]').html(`${score} (${severity})`);
225
+ }
215
226
  }
216
227
  }
@@ -0,0 +1,28 @@
1
+ .cvss-metric-label {
2
+ display: block;
3
+ margin-bottom: 0.375rem;
4
+
5
+ strong {
6
+ font-weight: 700;
7
+ margin-right: 0.25rem;
8
+ }
9
+
10
+ span {
11
+ color: var(--text-muted);
12
+ }
13
+
14
+ i {
15
+ color: var(--text-muted);
16
+ cursor: help;
17
+ margin-left: 0.25rem;
18
+ }
19
+ }
20
+
21
+ .cvss-btn-group {
22
+ margin-bottom: 1.5rem;
23
+ }
24
+
25
+ .cvss-group-title {
26
+ font-weight: 600;
27
+ margin-bottom: 0.75rem;
28
+ }
@@ -1,5 +1,223 @@
1
- @import '_bootstrap';
2
- @import 'font-awesome';
3
-
4
1
  @import 'hera/variables';
5
- @import 'hera/modules/buttons';
2
+ @import 'dradis/plugins/calculators/cvss/metric_labels';
3
+
4
+ .cvss-calculator {
5
+ padding-bottom: 2rem;
6
+
7
+ .cvss-metric-group {
8
+ border: 1px solid var(--border-color);
9
+ border-radius: 0.5rem;
10
+ margin-bottom: 1.25rem;
11
+ padding: 1.5rem;
12
+
13
+ &:last-child {
14
+ margin-bottom: 0;
15
+ }
16
+ }
17
+
18
+ .cvss-group-title {
19
+ border-bottom: 1px solid var(--border-color);
20
+ font-size: 0.875em;
21
+ letter-spacing: 0.04em;
22
+ margin-bottom: 1rem;
23
+ padding-bottom: 0.5rem;
24
+ text-transform: uppercase;
25
+ }
26
+
27
+ .cvss-metric-subgroup {
28
+ margin-top: 2rem;
29
+ width: 100%;
30
+
31
+ &:first-child {
32
+ margin-top: 1rem;
33
+ }
34
+ }
35
+
36
+ .cvss-btn-group.btn-group {
37
+ display: flex;
38
+ flex-wrap: wrap;
39
+ gap: 0.375rem;
40
+ margin-bottom: 1rem;
41
+
42
+ > .btn {
43
+ border-radius: 2rem !important;
44
+ flex: none;
45
+ font-size: 0.8rem;
46
+ font-weight: 400;
47
+ margin-left: 0;
48
+ padding: 0.3rem 0.75rem;
49
+ white-space: nowrap;
50
+
51
+ &:not(.active) {
52
+ background: var(--secondary-bg);
53
+ color: var(--text-muted);
54
+
55
+ &:hover {
56
+ background: $brand-100;
57
+ color: $primary;
58
+ }
59
+ }
60
+
61
+ &.active {
62
+ background: $primary;
63
+ border: 1px solid $primary;
64
+ box-shadow: 0.125rem 0.125rem 0.5rem 0 rgba($shadow-color-dark, 0.1);
65
+ color: $white;
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ .cvss-results-panel {
72
+ border: 1px solid var(--border-color);
73
+ border-radius: 0.5rem;
74
+ box-shadow: 0.125rem 0.125rem 0.5rem 0 rgba($shadow-color-dark, 0.1);
75
+ padding: 1.5rem;
76
+ position: sticky;
77
+ top: 1.5rem;
78
+ }
79
+
80
+ .cvss-score-display {
81
+ align-items: center;
82
+ display: flex;
83
+ margin-bottom: 1.5rem;
84
+ }
85
+
86
+ .cvss-score {
87
+ font-size: 3rem;
88
+ font-weight: 700;
89
+ line-height: 1;
90
+ margin-right: 0.75rem;
91
+ }
92
+
93
+ .cvss-severity-badge {
94
+ border: 1px solid transparent;
95
+ border-radius: 2rem;
96
+ display: inline-block;
97
+ font-size: 0.8rem;
98
+ font-weight: 600;
99
+ padding: 0.25rem 0.875rem;
100
+ }
101
+
102
+ .cvss-severity-none {
103
+ background: $grey-100;
104
+ border-color: $grey-800;
105
+ color: $grey-800;
106
+ }
107
+
108
+ .cvss-severity-low {
109
+ background: $blue-100;
110
+ border-color: $blue-700;
111
+ color: $blue-700;
112
+ }
113
+
114
+ .cvss-severity-medium {
115
+ background: $orange-100;
116
+ border-color: $orange-700;
117
+ color: $orange-700;
118
+ }
119
+
120
+ .cvss-severity-high {
121
+ background: $red-100;
122
+ border-color: $red-600;
123
+ color: $red-600;
124
+ }
125
+
126
+ .cvss-severity-critical {
127
+ background: mix($white, $lavender-dark, 85%);
128
+ border-color: darken($lavender-dark, 20%);
129
+ color: darken($lavender-dark, 20%);
130
+ }
131
+
132
+ .cvss-vector-display {
133
+ margin-bottom: 1.25rem;
134
+ }
135
+
136
+ .cvss-vector-label,
137
+ .cvss-output-label {
138
+ letter-spacing: 0.04em;
139
+ margin-bottom: 0.375rem;
140
+ text-transform: uppercase;
141
+ }
142
+
143
+ .cvss-output-label span {
144
+ letter-spacing: 0;
145
+ margin-top: 0.125rem;
146
+ text-transform: none;
147
+ }
148
+
149
+ .cvss-vector-copyable {
150
+ align-items: center;
151
+ background: var(--secondary-bg);
152
+ border: 1px solid var(--border-color);
153
+ border-radius: 0.375rem;
154
+ display: flex;
155
+ padding: 0.5rem 0.75rem;
156
+ }
157
+
158
+ .cvss-vector-string {
159
+ background-color: transparent;
160
+ color: var(--text-muted);
161
+ flex: 1;
162
+ font-size: 0.75rem;
163
+ overflow: hidden;
164
+ text-overflow: ellipsis;
165
+ white-space: nowrap;
166
+ }
167
+
168
+ .cvss-copy-btn {
169
+ background: none;
170
+ border: none;
171
+ flex-shrink: 0;
172
+ margin-left: 0.5rem;
173
+ padding: 0.125rem 0.375rem;
174
+
175
+ &:hover {
176
+ color: $primary;
177
+ }
178
+ }
179
+
180
+ .cvss-dradis-output {
181
+ margin-bottom: 0.5rem;
182
+ }
183
+
184
+ .cvss-output-textarea {
185
+ background: var(--secondary-bg) !important;
186
+ border: 1px solid var(--border-color);
187
+ border-radius: 0.375rem;
188
+ color: var(--text-muted);
189
+ font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo',
190
+ monospace;
191
+ font-size: 0.75rem;
192
+ line-height: 1.5;
193
+ resize: vertical;
194
+
195
+ &:focus {
196
+ border-color: $primary;
197
+ box-shadow: 0 0 0 0.2rem rgba($primary, 0.15);
198
+ }
199
+ }
200
+
201
+ .navbar-brand {
202
+ color: var(--text-default);
203
+
204
+ &:hover {
205
+ color: var(--text-default);
206
+ }
207
+ }
208
+
209
+ @media (max-width: 991px) {
210
+ .cvss-results-panel {
211
+ box-shadow: none;
212
+ position: static;
213
+ }
214
+
215
+ .cvss-score {
216
+ font-size: 2.25rem;
217
+ }
218
+
219
+ .cvss-calculator .cvss-btn-group .btn {
220
+ font-size: 0.75rem;
221
+ padding: 0.25rem 0.625rem;
222
+ }
223
+ }
@@ -1 +1,2 @@
1
1
  @import 'hera/variables';
2
+ @import 'dradis/plugins/calculators/cvss/metric_labels';
@@ -1,17 +1,17 @@
1
- <%= content_tag :div, class: 'page-header' do %>
2
- <h1 class="d-flex align-items-center justify-content-between">
3
- CVSS score calculator
4
- <div class="fs-3"><%= render 'dradis/plugins/calculators/cvss/version_menu' %></div>
5
- </h1>
6
- <% end %>
1
+ <div class="cvss-calculator" data-behavior="cvss-calculator">
2
+ <div class="page-header d-flex align-items-center justify-content-between mb-4">
3
+ <h1 class="m-0">CVSS v4.0 Calculator</h1>
4
+ <div class="fs-6"><%= render 'dradis/plugins/calculators/cvss/version_menu' %></div>
5
+ </div>
7
6
 
8
- <p class="lead">Use this page to calculate the <abbr title="Common Vulnerability Scoring System">CVSS</abbr> score of a given finding.</p>
7
+ <p class="lead">Calculate <abbr title="Common Vulnerability Scoring System">CVSS</abbr> scores for your findings.</p>
9
8
 
10
- <p class="alert alert-danger d-none" data-behavior="cvss-error"></p>
9
+ <p class="alert alert-danger d-none" data-behavior="cvss-error"></p>
11
10
 
12
- <div id="v3-index d-none" data-cvss-version="3">
13
- <%= render 'dradis/plugins/calculators/cvss/base/v3/index' %>
14
- </div>
15
- <div id="v4-index d-none" data-cvss-version="4">
16
- <%= render 'dradis/plugins/calculators/cvss/base/v4/index' %>
11
+ <div id="v3-index" class="d-none" data-cvss-version="3">
12
+ <%= render 'dradis/plugins/calculators/cvss/base/v3/index' %>
13
+ </div>
14
+ <div id="v4-index" data-cvss-version="4">
15
+ <%= render 'dradis/plugins/calculators/cvss/base/v4/index' %>
16
+ </div>
17
17
  </div>