Coverage for csaf/cvss.py: 96.40%

111 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-18 20:12:48 +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, RootModel 

9 

10from csaf.vuln_types 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 TargetDistributionType, 

33 UserInteractionType, 

34) 

35 

36 

37class ScoreType(RootModel[Annotated[float, Field(ge=0.0, le=10.0)]]): 

38 pass 

39 

40 

41class SeverityType(Enum): 

42 none = 'NONE' 

43 low = 'LOW' 

44 medium = 'MEDIUM' 

45 high = 'HIGH' 

46 critical = 'CRITICAL' 

47 

48 

49class Version(Enum): 

50 """ 

51 CVSS Version 

52 """ 

53 

54 two = '2.0' 

55 three_zero = '3.0' 

56 three_wun = '3.1' 

57 

58 

59class CVSS2(BaseModel): 

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

61 vector_string: Annotated[ 

62 str, 

63 Field( 

64 alias='vectorString', 

65 pattern=( 

66 '^((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:' 

67 '(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:' 

68 '(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:' 

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

70 ), 

71 ), 

72 ] 

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

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

75 authentication: Optional[AuthenticationType] = None 

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

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

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

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

80 exploitability: Optional[ExploitabilityType] = None 

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

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

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

84 collateral_damage_potential: Annotated[ 

85 Optional[CollateralDamagePotentialType], 

86 Field(alias='collateralDamagePotential'), 

87 ] = None 

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

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

90 None 

91 ) 

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

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

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

95 

96 @no_type_check 

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

98 kwargs.setdefault('by_alias', True) 

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

100 

101 

102class CVSS30(BaseModel): 

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

104 vector_string: Annotated[ 

105 str, 

106 Field( 

107 alias='vectorString', 

108 pattern=( 

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

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

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

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

113 ), 

114 ), 

115 ] 

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

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

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

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

120 scope: Optional[ScopeType] = None 

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

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

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

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

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

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

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

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

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

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

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

132 None 

133 ) 

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

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

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

137 modified_attack_complexity: Annotated[ 

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

139 ] = None 

140 modified_privileges_required: Annotated[ 

141 Optional[ModifiedPrivilegesRequiredType], 

142 Field(alias='modifiedPrivilegesRequired'), 

143 ] = None 

144 modified_user_interaction: Annotated[ 

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

146 ] = None 

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

148 modified_confidentiality_impact: Annotated[ 

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

150 ] = None 

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

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

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

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

155 

156 @no_type_check 

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

158 kwargs.setdefault('by_alias', True) 

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

160 

161 

162class CVSS31(BaseModel): 

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

164 vector_string: Annotated[ 

165 str, 

166 Field( 

167 alias='vectorString', 

168 pattern=( 

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

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

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

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

173 ), 

174 ), 

175 ] 

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

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

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

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

180 scope: Optional[ScopeType] = None 

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

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

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

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

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

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

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

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

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

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

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

192 None 

193 ) 

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

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

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

197 modified_attack_complexity: Annotated[ 

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

199 ] = None 

200 modified_privileges_required: Annotated[ 

201 Optional[ModifiedPrivilegesRequiredType], 

202 Field(alias='modifiedPrivilegesRequired'), 

203 ] = None 

204 modified_user_interaction: Annotated[ 

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

206 ] = None 

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

208 modified_confidentiality_impact: Annotated[ 

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

210 ] = None 

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

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

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

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

215 

216 @no_type_check 

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

218 kwargs.setdefault('by_alias', True) 

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