View Javadoc
1   /*
2    * This file is part of dependency-check-core.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2018 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.dependency;
19  
20  import org.sonatype.ossindex.service.api.cvss.Cvss3Severity;
21  
22  import java.io.Serializable;
23  import java.util.Arrays;
24  import java.util.HashMap;
25  import java.util.List;
26  
27  /**
28   * CVSS V3 scoring information.
29   *
30   * @author Jeremy Long
31   */
32  public class CvssV3 implements Serializable {
33  
34      /**
35       * Serial version UID.
36       */
37      private static final long serialVersionUID = -315810090425928920L;
38  
39      /**
40       * The CVSS v3 Base Metrics (that are required by the spec for any CVSS v3 Vector String)
41       */
42      private static final List<String> BASE_METRICS = Arrays.asList("AV", "AC", "PR", "UI", "S", "C", "I", "A");
43  
44      /**
45       * CVSS Availability Impact.
46       */
47      private final String attackVector;
48      /**
49       * CVSS Availability Impact.
50       */
51      private final String attackComplexity;
52      /**
53       * CVSS Availability Impact.
54       */
55      private final String privilegesRequired;
56      /**
57       * CVSS Availability Impact.
58       */
59      private final String userInteraction;
60      /**
61       * CVSS Availability Impact.
62       */
63      private final String scope;
64      /**
65       * CVSS Availability Impact.
66       */
67      private final String confidentialityImpact;
68      /**
69       * CVSS Availability Impact.
70       */
71      private final String integrityImpact;
72      /**
73       * CVSS Availability Impact.
74       */
75      private final String availabilityImpact;
76      /**
77       * CVSS Base Score.
78       */
79      private final float baseScore;
80      /**
81       * CVSS Base Severity.
82       */
83      private final String baseSeverity;
84      /**
85       * CVSSv3 Base Metric exploitability score.
86       */
87      private final Float exploitabilityScore;
88      /**
89       * CVSSv3 Base Metric impact score.
90       */
91      private final Float impactScore;
92      /**
93       * CVSS version.
94       */
95      private final String version;
96  
97      /**
98       * Constructs a new CVSS V3 object.
99       *
100      * @param attackVector the attack vector value
101      * @param attackComplexity the attack complexity value
102      * @param privilegesRequired the privileges required value
103      * @param userInteraction the user interaction value
104      * @param scope the scope value
105      * @param confidentialityImpact the confidentiality impact value
106      * @param integrityImpact the integrity impact value
107      * @param availabilityImpact the availability impact value
108      * @param baseScore the base score
109      * @param baseSeverity the base severity
110      */
111     //CSOFF: ParameterNumber
112     public CvssV3(String attackVector, String attackComplexity, String privilegesRequired,
113             String userInteraction, String scope, String confidentialityImpact, String integrityImpact,
114             String availabilityImpact, float baseScore, String baseSeverity) {
115         this(attackVector, attackComplexity, privilegesRequired, userInteraction, scope, confidentialityImpact,
116                 integrityImpact, availabilityImpact, baseScore, baseSeverity, null, null, null);
117     }
118 
119     /**
120      * Constructs a new CVSS V3 object.
121      *
122      * @param attackVector the attack vector value
123      * @param attackComplexity the attack complexity value
124      * @param privilegesRequired the privileges required value
125      * @param userInteraction the user interaction value
126      * @param scope the scope value
127      * @param confidentialityImpact the confidentiality impact value
128      * @param integrityImpact the integrity impact value
129      * @param availabilityImpact the availability impact value
130      * @param baseScore the base score
131      * @param baseSeverity the base severity
132      * @param exploitabilityScore the exploitability score
133      * @param impactScore the impact score
134      * @param version the CVSS version
135      */
136     public CvssV3(String attackVector, String attackComplexity, String privilegesRequired,
137             String userInteraction, String scope, String confidentialityImpact, String integrityImpact,
138             String availabilityImpact, float baseScore, String baseSeverity, Float exploitabilityScore, Float impactScore, String version) {
139         this.attackVector = attackVector;
140         this.attackComplexity = attackComplexity;
141         this.privilegesRequired = privilegesRequired;
142         this.userInteraction = userInteraction;
143         this.scope = scope;
144         this.confidentialityImpact = confidentialityImpact;
145         this.integrityImpact = integrityImpact;
146         this.availabilityImpact = availabilityImpact;
147         this.baseScore = baseScore;
148         this.baseSeverity = baseSeverity;
149         this.exploitabilityScore = exploitabilityScore;
150         this.impactScore = impactScore;
151         this.version = version;
152     }
153     //CSON: ParameterNumber
154 
155     /**
156      * Constructs a new CVSS V3 object from a CVSS v3.x Vector String representation and
157      * a CVSS V3 Base score.
158      *
159      * @param vectorString a CVSS v3 Vector String
160      * @param baseScore the CVSS v3 base score
161      * @throws IllegalArgumentException when the provided vectorString is not a valid
162      * <a href="https://www.first.org/cvss/specification-document#Vector-String">CVSS v3.x vector string</a>.
163      */
164     public CvssV3(String vectorString, float baseScore) {
165         if (!vectorString.startsWith("CVSS:3")) {
166             throw new IllegalArgumentException("Not a valid CVSSv3 vector string: " + vectorString);
167         }
168         this.version = vectorString.substring(5, vectorString.indexOf('/'));
169         final String[] metricStrings = vectorString.substring(vectorString.indexOf('/') + 1).split("/");
170         final HashMap<String, String> metrics = new HashMap<>();
171         for (int i = 0; i < metricStrings.length; i++) {
172             final String[] metricKeyVal = metricStrings[i].split(":");
173             if (metricKeyVal.length != 2) {
174                 throw new IllegalArgumentException(
175                         String.format("Not a valid CVSSv3 vector string '%s', invalid metric component '%s'",
176                                 vectorString, metricStrings[i]));
177             }
178             metrics.put(metricKeyVal[0], metricKeyVal[1]);
179         }
180         if (!metrics.keySet().containsAll(BASE_METRICS)) {
181             throw new IllegalArgumentException(
182                     String.format("Not a valid CVSSv3 vector string '%s'; missing one or more required Base Metrics;",
183                             vectorString));
184         }
185         this.attackVector = metrics.get("AV");
186         this.attackComplexity = metrics.get("AC");
187         this.privilegesRequired = metrics.get("PR");
188         this.userInteraction = metrics.get("UI");
189         this.scope = metrics.get("S");
190         this.confidentialityImpact = metrics.get("C");
191         this.integrityImpact = metrics.get("I");
192         this.availabilityImpact = metrics.get("A");
193         this.baseScore = baseScore;
194         this.baseSeverity = Cvss3Severity.of(baseScore).name();
195         this.exploitabilityScore = null;
196         this.impactScore = null;
197     }
198 
199     /**
200      * Get the value of attackVector.
201      *
202      * @return the value of attackVector
203      */
204     public String getAttackVector() {
205         return attackVector;
206     }
207 
208     /**
209      * Get the value of attackComplexity.
210      *
211      * @return the value of attackComplexity
212      */
213     public String getAttackComplexity() {
214         return attackComplexity;
215     }
216 
217     /**
218      * Get the value of privilegesRequired.
219      *
220      * @return the value of privilegesRequired
221      */
222     public String getPrivilegesRequired() {
223         return privilegesRequired;
224     }
225 
226     /**
227      * Get the value of userInteraction.
228      *
229      * @return the value of userInteraction
230      */
231     public String getUserInteraction() {
232         return userInteraction;
233     }
234 
235     /**
236      * Get the value of scope.
237      *
238      * @return the value of scope
239      */
240     public String getScope() {
241         return scope;
242     }
243 
244     /**
245      * Get the value of confidentialityImpact.
246      *
247      * @return the value of confidentialityImpact
248      */
249     public String getConfidentialityImpact() {
250         return confidentialityImpact;
251     }
252 
253     /**
254      * Get the value of integrityImpact.
255      *
256      * @return the value of integrityImpact
257      */
258     public String getIntegrityImpact() {
259         return integrityImpact;
260     }
261 
262     /**
263      * Get the value of availabilityImpact.
264      *
265      * @return the value of availabilityImpact
266      */
267     public String getAvailabilityImpact() {
268         return availabilityImpact;
269     }
270 
271     /**
272      * Get the value of baseScore.
273      *
274      * @return the value of baseScore
275      */
276     public float getBaseScore() {
277         return baseScore;
278     }
279 
280     /**
281      * Get the value of baseSeverity.
282      *
283      * @return the value of baseSeverity
284      */
285     public String getBaseSeverity() {
286         return baseSeverity;
287     }
288 
289     /**
290      * Get the value of version.
291      *
292      * @return the value of version
293      */
294     public String getVersion() {
295         return version;
296     }
297 
298     /**
299      * Returns the exploitabilityScore for the vulnerability.
300      *
301      * @return the exploitabilityScore
302      */
303     public Float getexploitabilityScore() {
304         return exploitabilityScore;
305     }
306 
307     /**
308      * Returns the impactScore for the vulnerability.
309      *
310      * @return the impactScore
311      */
312     public Float getimpactScore() {
313         return impactScore;
314     }
315 
316     @Override
317     public String toString() {
318         return String.format("CVSS:%s/AV:%s/AC:%s/PR:%s/UI:%s/S:%s/C:%s/I:%s/A:%s",
319                 version == null ? "" : version,
320                 attackVector == null ? "" : attackVector.substring(0, 1),
321                 attackComplexity == null ? "" : attackComplexity.substring(0, 1),
322                 privilegesRequired == null ? "" : privilegesRequired.substring(0, 1),
323                 userInteraction == null ? "" : userInteraction.substring(0, 1),
324                 scope == null ? "" : scope.substring(0, 1),
325                 confidentialityImpact == null ? "" : confidentialityImpact.substring(0, 1),
326                 integrityImpact == null ? "" : integrityImpact.substring(0, 1),
327                 availabilityImpact == null ? "" : availabilityImpact.substring(0, 1));
328     }
329 
330 }