Coverage for turvallisuusneuvonta/csaf/cvss/cvss.py: 96.33%

103 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-02-05 19:27:17 +00:00

1"""CSAF CVSS 2/3.0/3.1 proxy implementation.""" 

2 

3from __future__ import annotations 

4 

5from enum import Enum 

6from typing import Annotated, Optional, no_type_check 

7 

8from pydantic import BaseModel, Field 

9 

10from turvallisuusneuvonta.csaf.cvss.definitions import ( 

11 AccessComplexityType, 

12 AccessVectorType, 

13 AttackComplexityType, 

14 AttackVectorType, 

15 AuthenticationType, 

16 CiaRequirementType, 

17 CiaType, 

18 CollateralDamagePotentialType, 

19 ConfidenceType, 

20 ExploitabilityType, 

21 ExploitCodeMaturityType, 

22 ModifiedAttackComplexityType, 

23 ModifiedAttackVectorType, 

24 ModifiedCiaType, 

25 ModifiedPrivilegesRequiredType, 

26 ModifiedScopeType, 

27 ModifiedUserInteractionType, 

28 PrivilegesRequiredType, 

29 RemediationLevelType, 

30 ReportConfidenceType, 

31 ScopeType, 

32 ScoreType, 

33 SeverityType, 

34 TargetDistributionType, 

35 UserInteractionType, 

36) 

37 

38 

39class Version(Enum): 

40 """ 

41 CVSS Version 

42 """ 

43 

44 two = '2.0' 

45 three_zero = '3.0' 

46 three_wun = '3.1' 

47 

48 

49class CVSS2(BaseModel): 

50 version: Annotated[Version, Field(description='CVSS Version')] = Version.two 

51 vector_string: Annotated[ 

52 str, 

53 Field( 

54 alias='vectorString', 

55 pattern=( 

56 '^((AV:[NAL]|AC:[LMH]|Au:[MSN]|[CIA]:[NPC]|E:(U|POC|F|H|ND)|RL:(OF|TF|W|U|ND)|RC:(UC|UR|C|ND)|CDP:' 

57 '(N|L|LM|MH|H|ND)|TD:(N|L|M|H|ND)|[CIA]R:(L|M|H|ND))/)*(AV:[NAL]|AC:[LMH]|Au:[MSN]|[CIA]:[NPC]|E:' 

58 '(U|POC|F|H|ND)|RL:(OF|TF|W|U|ND)|RC:(UC|UR|C|ND)|CDP:(N|L|LM|MH|H|ND)|TD:(N|L|M|H|ND)|[CIA]R:' 

59 '(L|M|H|ND))$' 

60 ), 

61 ), 

62 ] 

63 access_vector: Annotated[Optional[AccessVectorType], Field(alias='accessVector')] = None 

64 access_complexity: Annotated[Optional[AccessComplexityType], Field(alias='accessComplexity')] = None 

65 authentication: Optional[AuthenticationType] = None 

66 confidentiality_impact: Annotated[Optional[CiaType], Field(alias='confidentialityImpact')] = None 

67 integrity_impact: Annotated[Optional[CiaType], Field(alias='integrityImpact')] = None 

68 availability_impact: Annotated[Optional[CiaType], Field(alias='availabilityImpact')] = None 

69 base_score: Annotated[ScoreType, Field(alias='baseScore')] 

70 exploitability: Optional[ExploitabilityType] = None 

71 remediation_level: Annotated[Optional[RemediationLevelType], Field(alias='remediationLevel')] = None 

72 report_confidence: Annotated[Optional[ReportConfidenceType], Field(alias='reportConfidence')] = None 

73 temporal_score: Annotated[Optional[ScoreType], Field(alias='temporalScore')] = None 

74 collateral_damage_potential: Annotated[ 

75 Optional[CollateralDamagePotentialType], 

76 Field(alias='collateralDamagePotential'), 

77 ] = None 

78 target_distribution: Annotated[Optional[TargetDistributionType], Field(alias='targetDistribution')] = None 

79 confidentiality_requirement: Annotated[Optional[CiaRequirementType], Field(alias='confidentialityRequirement')] = ( 

80 None 

81 ) 

82 integrity_requirement: Annotated[Optional[CiaRequirementType], Field(alias='integrityRequirement')] = None 

83 availability_requirement: Annotated[Optional[CiaRequirementType], Field(alias='availabilityRequirement')] = None 

84 environmental_score: Annotated[Optional[ScoreType], Field(alias='environmentalScore')] = None 

85 

86 @no_type_check 

87 def model_dump_json(self, *args, **kwargs): 

88 kwargs.setdefault('by_alias', True) 

89 return super().model_dump_json(*args, **kwargs) 

90 

91 

92class CVSS30(BaseModel): 

93 version: Annotated[Version, Field(description='CVSS Version')] = Version.three_zero 

94 vector_string: Annotated[ 

95 str, 

96 Field( 

97 alias='vectorString', 

98 pattern=( 

99 '^CVSS:3[.]0/((AV:[NALP]|AC:[LH]|PR:[UNLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|' 

100 '[CIA]R:[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XUNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])/)*(AV:[NALP]|' 

101 'AC:[LH]|PR:[UNLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|[CIA]R:[XLMH]|' 

102 'MAV:[XNALP]|MAC:[XLH]|MPR:[XUNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])$' 

103 ), 

104 ), 

105 ] 

106 attack_vector: Annotated[Optional[AttackVectorType], Field(alias='attackVector')] = None 

107 attack_complexity: Annotated[Optional[AttackComplexityType], Field(alias='attackComplexity')] = None 

108 privileges_required: Annotated[Optional[PrivilegesRequiredType], Field(alias='privilegesRequired')] = None 

109 user_interaction: Annotated[Optional[UserInteractionType], Field(alias='user_interaction')] = None 

110 scope: Optional[ScopeType] = None 

111 confidentiality_impact: Annotated[Optional[CiaType], Field(alias='confidentialityImpact')] = None 

112 integrity_impact: Annotated[Optional[CiaType], Field(alias='integrityImpact')] = None 

113 availability_impact: Annotated[Optional[CiaType], Field(alias='availabilityImpact')] = None 

114 base_score: Annotated[ScoreType, Field(alias='baseScore')] 

115 base_severity: Annotated[SeverityType, Field(alias='baseSeverity')] 

116 exploit_code_maturity: Annotated[Optional[ExploitCodeMaturityType], Field(alias='exploitCodeMaturity')] = None 

117 remediation_level: Annotated[Optional[RemediationLevelType], Field(alias='remediationLevel')] = None 

118 report_confidence: Annotated[Optional[ConfidenceType], Field(alias='reportConfidence')] = None 

119 temporal_score: Annotated[Optional[ScoreType], Field(alias='temporalScore')] = None 

120 temporal_severity: Annotated[Optional[SeverityType], Field(alias='temporalSeverity')] = None 

121 confidentiality_requirement: Annotated[Optional[CiaRequirementType], Field(alias='confidentialityRequirement')] = ( 

122 None 

123 ) 

124 integrity_requirement: Annotated[Optional[CiaRequirementType], Field(alias='integrityRequirement')] = None 

125 availability_requirement: Annotated[Optional[CiaRequirementType], Field(alias='availabilityRequirement')] = None 

126 modified_attack_vector: Annotated[Optional[ModifiedAttackVectorType], Field(alias='modifiedAttackVector')] = None 

127 modified_attack_complexity: Annotated[ 

128 Optional[ModifiedAttackComplexityType], Field(alias='modifiedAttackComplexity') 

129 ] = None 

130 modified_privileges_required: Annotated[ 

131 Optional[ModifiedPrivilegesRequiredType], 

132 Field(alias='modifiedPrivilegesRequired'), 

133 ] = None 

134 modified_user_interaction: Annotated[ 

135 Optional[ModifiedUserInteractionType], Field(alias='modifiedUserInteraction') 

136 ] = None 

137 modified_scope: Annotated[Optional[ModifiedScopeType], Field(alias='modifiedScope')] = None 

138 modified_confidentiality_impact: Annotated[ 

139 Optional[ModifiedCiaType], Field(alias='modifiedConfidentialityImpact') 

140 ] = None 

141 modified_integrity_impact: Annotated[Optional[ModifiedCiaType], Field(alias='modifiedIntegrityImpact')] = None 

142 modified_availability_impact: Annotated[Optional[ModifiedCiaType], Field(alias='modifiedAvailabilityImpact')] = None 

143 environmental_score: Annotated[Optional[ScoreType], Field(alias='environmentalScore')] = None 

144 environmental_severity: Annotated[Optional[SeverityType], Field(alias='environmentalSeverity')] = None 

145 

146 @no_type_check 

147 def model_dump_json(self, *args, **kwargs): 

148 kwargs.setdefault('by_alias', True) 

149 return super().model_dump_json(*args, **kwargs) 

150 

151 

152class CVSS31(BaseModel): 

153 version: Annotated[Version, Field(description='CVSS Version')] = Version.three_wun 

154 vector_string: Annotated[ 

155 str, 

156 Field( 

157 alias='vectorString', 

158 pattern=( 

159 '^CVSS:3[.]1/((AV:[NALP]|AC:[LH]|PR:[NLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:' 

160 '[XURC]|[CIA]R:[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])/)*' 

161 '(AV:[NALP]|AC:[LH]|PR:[NLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|[CIA]R:' 

162 '[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])$' 

163 ), 

164 ), 

165 ] 

166 attack_vector: Annotated[Optional[AttackVectorType], Field(alias='attackVector')] = None 

167 attack_complexity: Annotated[Optional[AttackComplexityType], Field(alias='attackComplexity')] = None 

168 privileges_required: Annotated[Optional[PrivilegesRequiredType], Field(alias='privilegesRequired')] = None 

169 user_interaction: Annotated[Optional[UserInteractionType], Field(alias='userInteraction')] = None 

170 scope: Optional[ScopeType] = None 

171 confidentiality_impact: Annotated[Optional[CiaType], Field(alias='confidentialityImpact')] = None 

172 integrity_impact: Annotated[Optional[CiaType], Field(alias='integrityImpact')] = None 

173 availability_impact: Annotated[Optional[CiaType], Field(alias='availabilityImpact')] = None 

174 base_score: Annotated[ScoreType, Field(alias='baseScore')] 

175 base_severity: Annotated[SeverityType, Field(alias='baseSeverity')] 

176 exploit_code_maturity: Annotated[Optional[ExploitCodeMaturityType], Field(alias='exploitCodeMaturity')] = None 

177 remediation_level: Annotated[Optional[RemediationLevelType], Field(alias='remediationLevel')] = None 

178 report_confidence: Annotated[Optional[ConfidenceType], Field(alias='reportConfidence')] = None 

179 temporal_score: Annotated[Optional[ScoreType], Field(alias='temporalScore')] = None 

180 temporal_severity: Annotated[Optional[SeverityType], Field(alias='temporalSeverity')] = None 

181 confidentiality_requirement: Annotated[Optional[CiaRequirementType], Field(alias='confidentialityRequirement')] = ( 

182 None 

183 ) 

184 integrity_requirement: Annotated[Optional[CiaRequirementType], Field(alias='integrityRequirement')] = None 

185 availability_requirement: Annotated[Optional[CiaRequirementType], Field(alias='availabilityRequirement')] = None 

186 modified_attack_vector: Annotated[Optional[ModifiedAttackVectorType], Field(alias='modifiedAttackVector')] = None 

187 modified_attack_complexity: Annotated[ 

188 Optional[ModifiedAttackComplexityType], Field(alias='modifiedAttackComplexity') 

189 ] = None 

190 modified_privileges_required: Annotated[ 

191 Optional[ModifiedPrivilegesRequiredType], 

192 Field(alias='modifiedPrivilegesRequired'), 

193 ] = None 

194 modified_user_interaction: Annotated[ 

195 Optional[ModifiedUserInteractionType], Field(alias='modifiedUserInteraction') 

196 ] = None 

197 modified_scope: Annotated[Optional[ModifiedScopeType], Field(alias='modifiedScope')] = None 

198 modified_confidentiality_impact: Annotated[ 

199 Optional[ModifiedCiaType], Field(alias='modifiedConfidentialityImpact') 

200 ] = None 

201 modified_integrity_impact: Annotated[Optional[ModifiedCiaType], Field(alias='modifiedIntegrityImpact')] = None 

202 modified_availability_impact: Annotated[Optional[ModifiedCiaType], Field(alias='modifiedAvailabilityImpact')] = None 

203 environmental_score: Annotated[Optional[ScoreType], Field(alias='environmentalScore')] = None 

204 environmental_severity: Annotated[Optional[SeverityType], Field(alias='environmentalSeverity')] = None 

205 

206 @no_type_check 

207 def model_dump_json(self, *args, **kwargs): 

208 kwargs.setdefault('by_alias', True) 

209 return super().model_dump_json(*args, **kwargs)