UNPKG

@neuralegion/cvss

Version:

The Common Vulnerability Scoring System ([CVSS](https://www.first.org/cvss/)) [score](https://www.first.org/cvss/specification-document#1-2-Scoring) calculator and validator library written in [TypeScript](https://www.typescriptlang.org/).

1,264 lines (1,252 loc) 50.9 kB
var BaseMetric$1; (function (BaseMetric) { BaseMetric["ATTACK_VECTOR"] = "AV"; BaseMetric["ATTACK_COMPLEXITY"] = "AC"; BaseMetric["PRIVILEGES_REQUIRED"] = "PR"; BaseMetric["USER_INTERACTION"] = "UI"; BaseMetric["SCOPE"] = "S"; BaseMetric["CONFIDENTIALITY"] = "C"; BaseMetric["INTEGRITY"] = "I"; BaseMetric["AVAILABILITY"] = "A"; })(BaseMetric$1 || (BaseMetric$1 = {})); var TemporalMetric$1; (function (TemporalMetric) { TemporalMetric["EXPLOIT_CODE_MATURITY"] = "E"; TemporalMetric["REMEDIATION_LEVEL"] = "RL"; TemporalMetric["REPORT_CONFIDENCE"] = "RC"; })(TemporalMetric$1 || (TemporalMetric$1 = {})); var EnvironmentalMetric$1; (function (EnvironmentalMetric) { EnvironmentalMetric["CONFIDENTIALITY_REQUIREMENT"] = "CR"; EnvironmentalMetric["INTEGRITY_REQUIREMENT"] = "IR"; EnvironmentalMetric["AVAILABILITY_REQUIREMENT"] = "AR"; EnvironmentalMetric["MODIFIED_ATTACK_VECTOR"] = "MAV"; EnvironmentalMetric["MODIFIED_ATTACK_COMPLEXITY"] = "MAC"; EnvironmentalMetric["MODIFIED_PRIVILEGES_REQUIRED"] = "MPR"; EnvironmentalMetric["MODIFIED_USER_INTERACTION"] = "MUI"; EnvironmentalMetric["MODIFIED_SCOPE"] = "MS"; EnvironmentalMetric["MODIFIED_CONFIDENTIALITY"] = "MC"; EnvironmentalMetric["MODIFIED_INTEGRITY"] = "MI"; EnvironmentalMetric["MODIFIED_AVAILABILITY"] = "MA"; })(EnvironmentalMetric$1 || (EnvironmentalMetric$1 = {})); const baseMetrics$1 = [ BaseMetric$1.ATTACK_VECTOR, BaseMetric$1.ATTACK_COMPLEXITY, BaseMetric$1.PRIVILEGES_REQUIRED, BaseMetric$1.USER_INTERACTION, BaseMetric$1.SCOPE, BaseMetric$1.CONFIDENTIALITY, BaseMetric$1.INTEGRITY, BaseMetric$1.AVAILABILITY ]; const temporalMetrics$1 = [ TemporalMetric$1.EXPLOIT_CODE_MATURITY, TemporalMetric$1.REMEDIATION_LEVEL, TemporalMetric$1.REPORT_CONFIDENCE ]; const environmentalMetrics$1 = [ EnvironmentalMetric$1.AVAILABILITY_REQUIREMENT, EnvironmentalMetric$1.CONFIDENTIALITY_REQUIREMENT, EnvironmentalMetric$1.INTEGRITY_REQUIREMENT, EnvironmentalMetric$1.MODIFIED_ATTACK_VECTOR, EnvironmentalMetric$1.MODIFIED_ATTACK_COMPLEXITY, EnvironmentalMetric$1.MODIFIED_PRIVILEGES_REQUIRED, EnvironmentalMetric$1.MODIFIED_USER_INTERACTION, EnvironmentalMetric$1.MODIFIED_SCOPE, EnvironmentalMetric$1.MODIFIED_CONFIDENTIALITY, EnvironmentalMetric$1.MODIFIED_INTEGRITY, EnvironmentalMetric$1.MODIFIED_AVAILABILITY ]; const baseMetricValues$1 = { [BaseMetric$1.ATTACK_VECTOR]: ['N', 'A', 'L', 'P'], [BaseMetric$1.ATTACK_COMPLEXITY]: ['L', 'H'], [BaseMetric$1.PRIVILEGES_REQUIRED]: ['N', 'L', 'H'], [BaseMetric$1.USER_INTERACTION]: ['N', 'R'], [BaseMetric$1.SCOPE]: ['U', 'C'], [BaseMetric$1.CONFIDENTIALITY]: ['N', 'L', 'H'], [BaseMetric$1.INTEGRITY]: ['N', 'L', 'H'], [BaseMetric$1.AVAILABILITY]: ['N', 'L', 'H'] }; const temporalMetricValues$1 = { [TemporalMetric$1.EXPLOIT_CODE_MATURITY]: ['X', 'H', 'F', 'P', 'U'], [TemporalMetric$1.REMEDIATION_LEVEL]: ['X', 'U', 'W', 'T', 'O'], [TemporalMetric$1.REPORT_CONFIDENCE]: ['X', 'C', 'R', 'U'] }; const environmentalMetricValues$1 = { [EnvironmentalMetric$1.CONFIDENTIALITY_REQUIREMENT]: ['X', 'H', 'M', 'L'], [EnvironmentalMetric$1.INTEGRITY_REQUIREMENT]: ['X', 'H', 'M', 'L'], [EnvironmentalMetric$1.AVAILABILITY_REQUIREMENT]: ['X', 'H', 'M', 'L'], [EnvironmentalMetric$1.MODIFIED_ATTACK_VECTOR]: ['X', 'N', 'A', 'L', 'P'], [EnvironmentalMetric$1.MODIFIED_ATTACK_COMPLEXITY]: ['X', 'L', 'H'], [EnvironmentalMetric$1.MODIFIED_PRIVILEGES_REQUIRED]: ['X', 'N', 'L', 'H'], [EnvironmentalMetric$1.MODIFIED_USER_INTERACTION]: ['X', 'N', 'R'], [EnvironmentalMetric$1.MODIFIED_SCOPE]: ['X', 'U', 'C'], [EnvironmentalMetric$1.MODIFIED_CONFIDENTIALITY]: ['X', 'N', 'L', 'H'], [EnvironmentalMetric$1.MODIFIED_INTEGRITY]: ['X', 'N', 'L', 'H'], [EnvironmentalMetric$1.MODIFIED_AVAILABILITY]: ['X', 'N', 'L', 'H'] }; const VERSION_REGEX = /^CVSS:(\d(?:\.\d)?)(.*)?$/; const parseVersion = (cvssStr) => { const versionRegexRes = VERSION_REGEX.exec(cvssStr); return versionRegexRes && versionRegexRes[1]; }; const parseVector = (cvssStr) => { const versionRegexRes = VERSION_REGEX.exec(cvssStr); return (versionRegexRes && versionRegexRes[2] && versionRegexRes[2].substring(1)); }; const parseMetrics = (vectorStr) => (vectorStr ? vectorStr.split('/') : []).map((metric) => { if (!metric) { return { key: '', value: '' }; } const parts = metric.split(':'); return { key: parts[0], value: parts[1] }; }); const parseMetricsAsMap$1 = (cvssStr) => parseMetrics(parseVector(cvssStr) || '').reduce((res, metric) => { if (res.has(metric.key)) { throw new Error(`Duplicated metric: "${metric.key}:${metric.value || ''}"`); } return res.set(metric.key, metric.value); }, new Map()); // https://www.first.org/cvss/v3.1/specification-document#7-4-Metric-Values const baseMetricValueScores$1 = { [BaseMetric$1.ATTACK_VECTOR]: { N: 0.85, A: 0.62, L: 0.55, P: 0.2 }, [BaseMetric$1.ATTACK_COMPLEXITY]: { L: 0.77, H: 0.44 }, [BaseMetric$1.PRIVILEGES_REQUIRED]: null, [BaseMetric$1.USER_INTERACTION]: { N: 0.85, R: 0.62 }, [BaseMetric$1.SCOPE]: { U: 0, C: 0 }, [BaseMetric$1.CONFIDENTIALITY]: { N: 0, L: 0.22, H: 0.56 }, [BaseMetric$1.INTEGRITY]: { N: 0, L: 0.22, H: 0.56 }, [BaseMetric$1.AVAILABILITY]: { N: 0, L: 0.22, H: 0.56 } }; const temporalMetricValueScores$1 = { [TemporalMetric$1.EXPLOIT_CODE_MATURITY]: { X: 1, U: 0.91, F: 0.97, P: 0.94, H: 1 }, [TemporalMetric$1.REMEDIATION_LEVEL]: { X: 1, O: 0.95, T: 0.96, W: 0.97, U: 1 }, [TemporalMetric$1.REPORT_CONFIDENCE]: { X: 1, U: 0.92, R: 0.96, C: 1 } }; const environmentalMetricValueScores$1 = { [EnvironmentalMetric$1.CONFIDENTIALITY_REQUIREMENT]: { M: 1, L: 0.5, H: 1.5, X: 1 }, [EnvironmentalMetric$1.INTEGRITY_REQUIREMENT]: { M: 1, L: 0.5, H: 1.5, X: 1 }, [EnvironmentalMetric$1.AVAILABILITY_REQUIREMENT]: { M: 1, L: 0.5, H: 1.5, X: 1 }, [EnvironmentalMetric$1.MODIFIED_ATTACK_VECTOR]: baseMetricValueScores$1[BaseMetric$1.ATTACK_VECTOR], [EnvironmentalMetric$1.MODIFIED_ATTACK_COMPLEXITY]: baseMetricValueScores$1[BaseMetric$1.ATTACK_COMPLEXITY], [EnvironmentalMetric$1.MODIFIED_PRIVILEGES_REQUIRED]: null, [EnvironmentalMetric$1.MODIFIED_USER_INTERACTION]: baseMetricValueScores$1[BaseMetric$1.USER_INTERACTION], [EnvironmentalMetric$1.MODIFIED_SCOPE]: baseMetricValueScores$1[BaseMetric$1.SCOPE], [EnvironmentalMetric$1.MODIFIED_CONFIDENTIALITY]: baseMetricValueScores$1[BaseMetric$1.CONFIDENTIALITY], [EnvironmentalMetric$1.MODIFIED_INTEGRITY]: baseMetricValueScores$1[BaseMetric$1.INTEGRITY], [EnvironmentalMetric$1.MODIFIED_AVAILABILITY]: baseMetricValueScores$1[BaseMetric$1.AVAILABILITY] }; const getPrivilegesRequiredNumericValue = (value, scopeValue) => { if (scopeValue !== 'U' && scopeValue !== 'C') { throw new Error(`Unknown Scope value: ${scopeValue}`); } switch (value) { case 'N': return 0.85; case 'L': return scopeValue === 'U' ? 0.62 : 0.68; case 'H': return scopeValue === 'U' ? 0.27 : 0.5; default: throw new Error(`Unknown PrivilegesRequired value: ${value}`); } }; const getMetricValue = (metric, metricsMap) => { if (!metricsMap.has(metric)) { throw new Error(`Missing metric: ${metric}`); } return metricsMap.get(metric); }; const getMetricNumericValue$1 = (metric, metricsMap) => { const value = getMetricValue(metric || TemporalMetric$1 || EnvironmentalMetric$1, metricsMap); if (metric === BaseMetric$1.PRIVILEGES_REQUIRED) { return getPrivilegesRequiredNumericValue(value, getMetricValue(BaseMetric$1.SCOPE, metricsMap)); } if (metric === EnvironmentalMetric$1.MODIFIED_PRIVILEGES_REQUIRED) { return getPrivilegesRequiredNumericValue(value, getMetricValue(EnvironmentalMetric$1.MODIFIED_SCOPE, metricsMap)); } const score = { ...baseMetricValueScores$1, ...temporalMetricValueScores$1, ...environmentalMetricValueScores$1 }[metric]; if (!score) { throw new Error(`Internal error. Missing metric score: ${metric}`); } return score[value]; }; // ISS = 1 - [ (1 - Confidentiality) × (1 - Integrity) × (1 - Availability) ] const calculateIss = (metricsMap) => { const confidentiality = getMetricNumericValue$1(BaseMetric$1.CONFIDENTIALITY, metricsMap); const integrity = getMetricNumericValue$1(BaseMetric$1.INTEGRITY, metricsMap); const availability = getMetricNumericValue$1(BaseMetric$1.AVAILABILITY, metricsMap); return 1 - (1 - confidentiality) * (1 - integrity) * (1 - availability); }; // https://www.first.org/cvss/v3.1/specification-document#7-3-Environmental-Metrics-Equations // MISS = Minimum ( 1 - [ (1 - ConfidentialityRequirement × ModifiedConfidentiality) × (1 - IntegrityRequirement × ModifiedIntegrity) × (1 - AvailabilityRequirement × ModifiedAvailability) ], 0.915) const calculateMiss = (metricsMap) => { const rConfidentiality = getMetricNumericValue$1(EnvironmentalMetric$1.CONFIDENTIALITY_REQUIREMENT, metricsMap); const mConfidentiality = getMetricNumericValue$1(EnvironmentalMetric$1.MODIFIED_CONFIDENTIALITY, metricsMap); const rIntegrity = getMetricNumericValue$1(EnvironmentalMetric$1.INTEGRITY_REQUIREMENT, metricsMap); const mIntegrity = getMetricNumericValue$1(EnvironmentalMetric$1.MODIFIED_INTEGRITY, metricsMap); const rAvailability = getMetricNumericValue$1(EnvironmentalMetric$1.AVAILABILITY_REQUIREMENT, metricsMap); const mAvailability = getMetricNumericValue$1(EnvironmentalMetric$1.MODIFIED_AVAILABILITY, metricsMap); return Math.min(1 - (1 - rConfidentiality * mConfidentiality) * (1 - rIntegrity * mIntegrity) * (1 - rAvailability * mAvailability), 0.915); }; // https://www.first.org/cvss/v3.1/specification-document#7-1-Base-Metrics-Equations // Impact = // If Scope is Unchanged 6.42 × ISS // If Scope is Changed 7.52 × (ISS - 0.029) - 3.25 × (ISS - 0.02)^15 const calculateImpact = (metricsMap, iss) => metricsMap.get(BaseMetric$1.SCOPE) === 'U' ? 6.42 * iss : 7.52 * (iss - 0.029) - 3.25 * Math.pow(iss - 0.02, 15); // https://www.first.org/cvss/v3-0/specification-document#8-1-Base // ModifiedImpact = // If ModifiedScope is Unchanged 6.42 × MISS // If ModifiedScope is Changed 7.52 × (MISS - 0.029) - 3.25 × (MISS - 0.02)^15 // ModifiedExploitability = 8.22 × ModifiedAttackVector × ModifiedAttackComplexity × ModifiedPrivilegesRequired × ModifiedUserInteraction const calculateModifiedImpactV3 = (metricsMap, miss) => metricsMap.get(EnvironmentalMetric$1.MODIFIED_SCOPE) === 'U' ? 6.42 * miss : 7.52 * (miss - 0.029) - 3.25 * Math.pow(miss * 1 - 0.02, 15); // https://www.first.org/cvss/v3.1/specification-document#7-3-Environmental-Metrics-Equations // ModifiedImpact = // If ModifiedScope is Unchanged 6.42 × MISS // If ModifiedScope is Changed 7.52 × (MISS - 0.029) - 3.25 × (MISS × 0.9731 - 0.02)^13 // ModifiedExploitability = 8.22 × ModifiedAttackVector × ModifiedAttackComplexity × ModifiedPrivilegesRequired × ModifiedUserInteraction const calculateModifiedImpactV31 = (metricsMap, miss) => metricsMap.get(EnvironmentalMetric$1.MODIFIED_SCOPE) === 'U' ? 6.42 * miss : 7.52 * (miss - 0.029) - 3.25 * Math.pow(miss * 0.9731 - 0.02, 13); const calculateModifiedImpact = (metricsMap, miss, versionStr) => versionStr === '3.0' ? calculateModifiedImpactV3(metricsMap, miss) : calculateModifiedImpactV31(metricsMap, miss); // https://www.first.org/cvss/v3.1/specification-document#7-1-Base-Metrics-Equations // Exploitability = 8.22 × AttackVector × AttackComplexity × PrivilegesRequired × UserInteraction const calculateExploitability = (metricsMap) => 8.22 * getMetricNumericValue$1(BaseMetric$1.ATTACK_VECTOR, metricsMap) * getMetricNumericValue$1(BaseMetric$1.ATTACK_COMPLEXITY, metricsMap) * getMetricNumericValue$1(BaseMetric$1.PRIVILEGES_REQUIRED, metricsMap) * getMetricNumericValue$1(BaseMetric$1.USER_INTERACTION, metricsMap); // https://www.first.org/cvss/v3.1/specification-document#7-3-Environmental-Metrics-Equations // Exploitability = 8.22 × ModifiedAttackVector × ModifiedAttackComplexity × ModifiedPrivilegesRequired × ModifiedUserInteraction const calculateModifiedExploitability = (metricsMap) => 8.22 * getMetricNumericValue$1(EnvironmentalMetric$1.MODIFIED_ATTACK_VECTOR, metricsMap) * getMetricNumericValue$1(EnvironmentalMetric$1.MODIFIED_ATTACK_COMPLEXITY, metricsMap) * getMetricNumericValue$1(EnvironmentalMetric$1.MODIFIED_PRIVILEGES_REQUIRED, metricsMap) * getMetricNumericValue$1(EnvironmentalMetric$1.MODIFIED_USER_INTERACTION, metricsMap); // https://www.first.org/cvss/v3.1/specification-document#Appendix-A---Floating-Point-Rounding const roundUp = (input) => { const intInput = Math.round(input * 100000); return intInput % 10000 === 0 ? intInput / 100000 : (Math.floor(intInput / 10000) + 1) / 10; }; const round$1 = (input) => { const intInput = Math.round(input * 100000); return Math.round(intInput / 10000) / 10; }; const modifiedMetricsMap = { MAV: BaseMetric$1.ATTACK_VECTOR, MAC: BaseMetric$1.ATTACK_COMPLEXITY, MPR: BaseMetric$1.PRIVILEGES_REQUIRED, MUI: BaseMetric$1.USER_INTERACTION, MS: BaseMetric$1.SCOPE, MC: BaseMetric$1.CONFIDENTIALITY, MI: BaseMetric$1.INTEGRITY, MA: BaseMetric$1.AVAILABILITY }; // When Modified Temporal metric value is 'Not Defined' ('X'), which is the default value, // then Base metric value should be used. const populateTemporalMetricDefaults$1 = (metricsMap) => { [...temporalMetrics$1].forEach((metric) => { if (!metricsMap.has(metric)) { metricsMap.set(metric, 'X'); } }); return metricsMap; }; const populateEnvironmentalMetricDefaults$1 = (metricsMap) => { [...environmentalMetrics$1].forEach((metric) => { if (!metricsMap.has(metric)) { metricsMap.set(metric, 'X'); } if (metricsMap.get(metric) === 'X') { metricsMap.set(metric, metricsMap.has(modifiedMetricsMap[metric]) ? metricsMap.get(modifiedMetricsMap[metric]) : 'X'); } }); return metricsMap; }; class CvssV3Calculator { calculate(cvssString) { const metricsMap = parseMetricsAsMap$1(cvssString); const versionStr = parseVersion(cvssString); const baseResult = this.calculateBaseScore(metricsMap, versionStr); const temporalResult = this.calculateTemporalScore(baseResult); const environmentalResult = this.calculateEnvironmentalScore(metricsMap, versionStr); return { ...baseResult, ...temporalResult, ...environmentalResult }; } /** * Calculate the base score for a CVSS v3.x string */ calculateBaseScore(metricsMap, versionStr) { const iss = calculateIss(metricsMap); const impact = calculateImpact(metricsMap, iss); const exploitability = calculateExploitability(metricsMap); const scopeUnchanged = metricsMap.get(BaseMetric$1.SCOPE) === 'U'; const baseScore = impact <= 0 ? 0 : scopeUnchanged ? roundUp(Math.min(impact + exploitability, 10)) : roundUp(Math.min(1.08 * (impact + exploitability), 10)); return { version: versionStr, baseScore, baseImpact: impact <= 0 ? 0 : round$1(impact), baseExploitability: exploitability <= 0 ? 0 : round$1(exploitability), metrics: metricsMap }; } /** * Calculate the temporal score for a CVSS v3.x string */ calculateTemporalScore(baseResult) { // populate temp metrics const metricsMap = populateTemporalMetricDefaults$1(baseResult.metrics); const temporalScore = roundUp(baseResult.baseScore * getMetricNumericValue$1(TemporalMetric$1.REPORT_CONFIDENCE, metricsMap) * getMetricNumericValue$1(TemporalMetric$1.EXPLOIT_CODE_MATURITY, metricsMap) * getMetricNumericValue$1(TemporalMetric$1.REMEDIATION_LEVEL, metricsMap)); return { temporalScore }; } /** * Calculate the environmental score for a CVSS v3.x string */ calculateEnvironmentalScore(metricsMap, versionStr) { metricsMap = populateTemporalMetricDefaults$1(metricsMap); metricsMap = populateEnvironmentalMetricDefaults$1(metricsMap); const miss = calculateMiss(metricsMap); const impact = calculateModifiedImpact(metricsMap, miss, versionStr); const exploitability = calculateModifiedExploitability(metricsMap); const scopeUnchanged = metricsMap.get(EnvironmentalMetric$1.MODIFIED_SCOPE) === 'U'; const environmentalScore = impact <= 0 ? 0 : scopeUnchanged ? roundUp(roundUp(Math.min(impact + exploitability, 10)) * getMetricNumericValue$1(TemporalMetric$1.EXPLOIT_CODE_MATURITY, metricsMap) * getMetricNumericValue$1(TemporalMetric$1.REMEDIATION_LEVEL, metricsMap) * getMetricNumericValue$1(TemporalMetric$1.REPORT_CONFIDENCE, metricsMap)) : roundUp(roundUp(Math.min(1.08 * (impact + exploitability), 10)) * getMetricNumericValue$1(TemporalMetric$1.EXPLOIT_CODE_MATURITY, metricsMap) * getMetricNumericValue$1(TemporalMetric$1.REMEDIATION_LEVEL, metricsMap) * getMetricNumericValue$1(TemporalMetric$1.REPORT_CONFIDENCE, metricsMap)); return { environmentalScore, modifiedImpact: impact <= 0 ? 0 : round$1(impact), modifiedExploitability: exploitability <= 0 ? 0 : round$1(exploitability) }; } } var BaseMetric; (function (BaseMetric) { BaseMetric["ACCESS_VECTOR"] = "AV"; BaseMetric["ACCESS_COMPLEXITY"] = "AC"; BaseMetric["AUTHENTICATION"] = "Au"; BaseMetric["CONFIDENTIALITY_IMPACT"] = "C"; BaseMetric["INTEGRITY_IMPACT"] = "I"; BaseMetric["AVAILABILITY_IMPACT"] = "A"; })(BaseMetric || (BaseMetric = {})); var TemporalMetric; (function (TemporalMetric) { TemporalMetric["EXPLOITABILITY"] = "E"; TemporalMetric["REMEDIATION_LEVEL"] = "RL"; TemporalMetric["REPORT_CONFIDENCE"] = "RC"; })(TemporalMetric || (TemporalMetric = {})); var EnvironmentalMetric; (function (EnvironmentalMetric) { EnvironmentalMetric["COLLATERAL_DAMAGE_POTENTIAL"] = "CDP"; EnvironmentalMetric["TARGET_DISTRIBUTION"] = "TD"; EnvironmentalMetric["CONFIDENTIALITY_REQUIREMENT"] = "CR"; EnvironmentalMetric["INTEGRITY_REQUIREMENT"] = "IR"; EnvironmentalMetric["AVAILABILITY_REQUIREMENT"] = "AR"; })(EnvironmentalMetric || (EnvironmentalMetric = {})); const baseMetrics = [ BaseMetric.ACCESS_VECTOR, BaseMetric.ACCESS_COMPLEXITY, BaseMetric.AUTHENTICATION, BaseMetric.CONFIDENTIALITY_IMPACT, BaseMetric.INTEGRITY_IMPACT, BaseMetric.AVAILABILITY_IMPACT ]; const temporalMetrics = [ TemporalMetric.EXPLOITABILITY, TemporalMetric.REMEDIATION_LEVEL, TemporalMetric.REPORT_CONFIDENCE ]; const environmentalMetrics = [ EnvironmentalMetric.COLLATERAL_DAMAGE_POTENTIAL, EnvironmentalMetric.TARGET_DISTRIBUTION, EnvironmentalMetric.CONFIDENTIALITY_REQUIREMENT, EnvironmentalMetric.INTEGRITY_REQUIREMENT, EnvironmentalMetric.AVAILABILITY_REQUIREMENT ]; const baseMetricValues = { [BaseMetric.ACCESS_VECTOR]: ['L', 'A', 'N'], [BaseMetric.ACCESS_COMPLEXITY]: ['H', 'M', 'L'], [BaseMetric.AUTHENTICATION]: ['M', 'S', 'N'], [BaseMetric.CONFIDENTIALITY_IMPACT]: ['N', 'P', 'C'], [BaseMetric.INTEGRITY_IMPACT]: ['N', 'P', 'C'], [BaseMetric.AVAILABILITY_IMPACT]: ['N', 'P', 'C'] }; const temporalMetricValues = { [TemporalMetric.EXPLOITABILITY]: ['U', 'POC', 'F', 'H', 'ND'], [TemporalMetric.REMEDIATION_LEVEL]: ['OF', 'TF', 'W', 'U', 'ND'], [TemporalMetric.REPORT_CONFIDENCE]: ['UC', 'UR', 'C', 'ND'] }; const environmentalMetricValues = { [EnvironmentalMetric.COLLATERAL_DAMAGE_POTENTIAL]: [ 'N', 'L', 'LM', 'MH', 'H', 'ND' ], [EnvironmentalMetric.TARGET_DISTRIBUTION]: ['N', 'L', 'M', 'H', 'ND'], [EnvironmentalMetric.CONFIDENTIALITY_REQUIREMENT]: ['L', 'M', 'H', 'ND'], [EnvironmentalMetric.INTEGRITY_REQUIREMENT]: ['L', 'M', 'H', 'ND'], [EnvironmentalMetric.AVAILABILITY_REQUIREMENT]: ['L', 'M', 'H', 'ND'] }; const baseMetricValueScores = { [BaseMetric.ACCESS_VECTOR]: { L: 0.395, A: 0.646, N: 1.0 }, [BaseMetric.ACCESS_COMPLEXITY]: { H: 0.35, M: 0.61, L: 0.71 }, [BaseMetric.AUTHENTICATION]: { M: 0.45, S: 0.56, N: 0.704 }, [BaseMetric.CONFIDENTIALITY_IMPACT]: { N: 0, P: 0.275, C: 0.66 }, [BaseMetric.INTEGRITY_IMPACT]: { N: 0, P: 0.275, C: 0.66 }, [BaseMetric.AVAILABILITY_IMPACT]: { N: 0, P: 0.275, C: 0.66 } }; const temporalMetricValueScores = { [TemporalMetric.EXPLOITABILITY]: { ND: 1.0, U: 0.85, POC: 0.9, F: 0.95, H: 1.0 }, [TemporalMetric.REMEDIATION_LEVEL]: { ND: 1.0, OF: 0.87, TF: 0.9, W: 0.95, U: 1.0 }, [TemporalMetric.REPORT_CONFIDENCE]: { ND: 1.0, UC: 0.9, UR: 0.95, C: 1.0 } }; const environmentalMetricValueScores = { [EnvironmentalMetric.COLLATERAL_DAMAGE_POTENTIAL]: { ND: 0, N: 0, L: 0.1, LM: 0.3, MH: 0.4, H: 0.5 }, [EnvironmentalMetric.TARGET_DISTRIBUTION]: { ND: 1.0, N: 0, L: 0.25, M: 0.75, H: 1.0 }, [EnvironmentalMetric.CONFIDENTIALITY_REQUIREMENT]: { ND: 1.0, L: 0.5, M: 1.0, H: 1.51 }, [EnvironmentalMetric.INTEGRITY_REQUIREMENT]: { ND: 1.0, L: 0.5, M: 1.0, H: 1.51 }, [EnvironmentalMetric.AVAILABILITY_REQUIREMENT]: { ND: 1.0, L: 0.5, M: 1.0, H: 1.51 } }; const getMetricNumericValue = (metric, metricsMap) => { if (!metricsMap.has(metric)) { throw new Error(`Missing metric: ${metric}`); } const score = { ...baseMetricValueScores, ...temporalMetricValueScores, ...environmentalMetricValueScores }[metric]; if (!score) { throw new Error(`Internal error. Missing metric score: ${metric}`); } return score[metricsMap.get(metric)]; }; const round = (input) => Math.round(input * 10) / 10; const populateTemporalMetricDefaults = (metricsMap) => { [...temporalMetrics].forEach((metric) => { if (!metricsMap.has(metric)) { metricsMap.set(metric, 'ND'); } }); return metricsMap; }; const populateEnvironmentalMetricDefaults = (metricsMap) => { [...environmentalMetrics].forEach((metric) => { if (!metricsMap.has(metric)) { metricsMap.set(metric, 'ND'); } }); return metricsMap; }; class CvssV2Calculator { calculate(cvssString) { const metricsMap = parseMetricsAsMap$1(cvssString); const baseResult = this.calculateBaseScore(metricsMap); const temporalResult = this.calculateTemporalScore(baseResult, metricsMap); const environmentalResult = this.calculateEnvironmentalScore(baseResult, metricsMap); return { ...baseResult, ...temporalResult, ...environmentalResult, version: '2.0', metrics: metricsMap }; } calculateBaseScore(metricsMap) { const impact = this.calculateImpact(metricsMap); const exploitability = this.calculateExploitability(metricsMap); const fImpact = impact === 0 ? 0 : 1.176; const baseScore = (0.6 * impact + 0.4 * exploitability - 1.5) * fImpact; return { baseScore: round(baseScore), baseImpact: round(impact), baseExploitability: round(exploitability) }; } calculateImpact(metricsMap) { const c = getMetricNumericValue(BaseMetric.CONFIDENTIALITY_IMPACT, metricsMap); const i = getMetricNumericValue(BaseMetric.INTEGRITY_IMPACT, metricsMap); const a = getMetricNumericValue(BaseMetric.AVAILABILITY_IMPACT, metricsMap); return 10.41 * (1 - (1 - c) * (1 - i) * (1 - a)); } calculateExploitability(metricsMap) { const av = getMetricNumericValue(BaseMetric.ACCESS_VECTOR, metricsMap); const ac = getMetricNumericValue(BaseMetric.ACCESS_COMPLEXITY, metricsMap); const au = getMetricNumericValue(BaseMetric.AUTHENTICATION, metricsMap); return 20 * av * ac * au; } calculateTemporalScore(baseResult, metricsMap) { populateTemporalMetricDefaults(metricsMap); const e = getMetricNumericValue(TemporalMetric.EXPLOITABILITY, metricsMap); const rl = getMetricNumericValue(TemporalMetric.REMEDIATION_LEVEL, metricsMap); const rc = getMetricNumericValue(TemporalMetric.REPORT_CONFIDENCE, metricsMap); const temporalScore = round(baseResult.baseScore * e * rl * rc); return { temporalScore }; } calculateEnvironmentalScore(baseResult, metricsMap) { populateEnvironmentalMetricDefaults(metricsMap); const cdp = getMetricNumericValue(EnvironmentalMetric.COLLATERAL_DAMAGE_POTENTIAL, metricsMap); const td = getMetricNumericValue(EnvironmentalMetric.TARGET_DISTRIBUTION, metricsMap); // Adjusted Impact const c = getMetricNumericValue(BaseMetric.CONFIDENTIALITY_IMPACT, metricsMap); const i = getMetricNumericValue(BaseMetric.INTEGRITY_IMPACT, metricsMap); const a = getMetricNumericValue(BaseMetric.AVAILABILITY_IMPACT, metricsMap); const cr = getMetricNumericValue(EnvironmentalMetric.CONFIDENTIALITY_REQUIREMENT, metricsMap); const ir = getMetricNumericValue(EnvironmentalMetric.INTEGRITY_REQUIREMENT, metricsMap); const ar = getMetricNumericValue(EnvironmentalMetric.AVAILABILITY_REQUIREMENT, metricsMap); const adjustedImpact = Math.min(10, 10.41 * (1 - (1 - c * cr) * (1 - i * ir) * (1 - a * ar))); // Adjusted Base const fImpact = adjustedImpact === 0 ? 0 : 1.176; const adjustedBase = round((0.6 * adjustedImpact + 0.4 * baseResult.baseExploitability - 1.5) * fImpact); // Adjusted Temporal const e = getMetricNumericValue(TemporalMetric.EXPLOITABILITY, metricsMap); const rl = getMetricNumericValue(TemporalMetric.REMEDIATION_LEVEL, metricsMap); const rc = getMetricNumericValue(TemporalMetric.REPORT_CONFIDENCE, metricsMap); const adjustedTemporal = round(adjustedBase * e * rl * rc); const environmentalScore = round((adjustedTemporal + (10 - adjustedTemporal) * cdp) * td); return { environmentalScore }; } } const createCvssCalculator = (version) => { switch (version) { case '2.0': return new CvssV2Calculator(); case '3.0': case '3.1': return new CvssV3Calculator(); default: throw new Error(`Unsupported CVSS version: ${version}`); } }; const validateVector = (vectorStr) => { if (!vectorStr || vectorStr.includes('//')) { throw new Error('Invalid CVSS string'); } }; const checkUnknownMetrics = (metricsMap, knownMetrics) => { [...metricsMap.keys()].forEach((userMetric) => { if (!knownMetrics.includes(userMetric)) { throw new Error(`Unknown CVSS metric "${userMetric}". Allowed metrics: ${knownMetrics.join(', ')}`); } }); }; const checkMandatoryMetrics = (metricsMap, metrics, humanizer) => { metrics.forEach((metric) => { if (!metricsMap.has(metric)) { const metricName = humanizer ? humanizer.humanizeMetric(metric) : metric; throw new Error(`Missing mandatory CVSS metric ${metricName}`); } }); }; const checkMetricsValues = (metricsMap, metrics, metricsValues, humanizer) => { metrics.forEach((metric) => { const userValue = metricsMap.get(metric); if (!userValue) { return; } if (!metricsValues[metric].includes(userValue)) { let errorMsg = ''; if (humanizer) { const allowedValuesHumanized = metricsValues[metric] .map((value) => `${value} (${humanizer.humanizeMetricValue(value, metric)})`) .join(', '); errorMsg = `Invalid value for CVSS metric ${metric} (${humanizer.humanizeMetric(metric)})${userValue ? `: ${userValue}` : ''}. Allowed values: ${allowedValuesHumanized}`; } else { const allowedValues = metricsValues[metric].join(', '); errorMsg = `Invalid value for CVSS metric ${metric}: ${userValue}. Allowed values: ${allowedValues}`; } throw new Error(errorMsg); } }); }; const validateByKnownMaps = (cvssStr, validateVersion, metrics, knownMetricsValues, humanizer) => { if (!cvssStr || !cvssStr.startsWith('CVSS:')) { throw new Error('CVSS vector must start with "CVSS:"'); } const versionStr = parseVersion(cvssStr); validateVersion(versionStr); const vectorStr = parseVector(cvssStr); validateVector(vectorStr); const allMetrics = [ ...metrics.base, ...metrics.temporal, ...metrics.environmental ]; const metricsMap = parseMetricsAsMap$1(cvssStr); checkMandatoryMetrics(metricsMap, metrics.base, humanizer); checkUnknownMetrics(metricsMap, allMetrics); checkMetricsValues(metricsMap, allMetrics, knownMetricsValues, humanizer); const isTemporal = [...metricsMap.keys()].some((metric) => metrics.temporal.includes(metric)); const isEnvironmental = [...metricsMap.keys()].some((metric) => metrics.environmental.includes(metric)); return { metricsMap, isTemporal, isEnvironmental, versionStr }; }; // eslint-disable-next-line complexity const humanizeMetric$1 = (metric) => { switch (metric) { case BaseMetric.ACCESS_VECTOR: return 'Access Vector'; case BaseMetric.ACCESS_COMPLEXITY: return 'Access Complexity'; case BaseMetric.AUTHENTICATION: return 'Authentication'; case BaseMetric.CONFIDENTIALITY_IMPACT: return 'Confidentiality Impact'; case BaseMetric.INTEGRITY_IMPACT: return 'Integrity Impact'; case BaseMetric.AVAILABILITY_IMPACT: return 'Availability Impact'; case TemporalMetric.EXPLOITABILITY: return 'Exploitability'; case TemporalMetric.REMEDIATION_LEVEL: return 'Remediation Level'; case TemporalMetric.REPORT_CONFIDENCE: return 'Report Confidence'; case EnvironmentalMetric.COLLATERAL_DAMAGE_POTENTIAL: return 'Collateral Damage Potential'; case EnvironmentalMetric.TARGET_DISTRIBUTION: return 'Target Distribution'; case EnvironmentalMetric.CONFIDENTIALITY_REQUIREMENT: return 'Confidentiality Requirement'; case EnvironmentalMetric.INTEGRITY_REQUIREMENT: return 'Integrity Requirement'; case EnvironmentalMetric.AVAILABILITY_REQUIREMENT: return 'Availability Requirement'; default: return 'Unknown'; } }; // eslint-disable-next-line complexity const humanizeMetricValue$1 = (value, metric) => { switch (metric) { case BaseMetric.ACCESS_VECTOR: switch (value) { case 'L': return 'Local'; case 'A': return 'Adjacent Network'; case 'N': return 'Network'; } break; case BaseMetric.ACCESS_COMPLEXITY: switch (value) { case 'H': return 'High'; case 'M': return 'Medium'; case 'L': return 'Low'; } break; case BaseMetric.AUTHENTICATION: switch (value) { case 'M': return 'Multiple'; case 'S': return 'Single'; case 'N': return 'None'; } break; case BaseMetric.CONFIDENTIALITY_IMPACT: case BaseMetric.INTEGRITY_IMPACT: case BaseMetric.AVAILABILITY_IMPACT: switch (value) { case 'N': return 'None'; case 'P': return 'Partial'; case 'C': return 'Complete'; } break; case TemporalMetric.EXPLOITABILITY: switch (value) { case 'U': return 'Unproven that exploit exists'; case 'POC': return 'Proof of concept code'; case 'F': return 'Functional exploit exists'; case 'H': return 'High'; case 'ND': return 'Not Defined'; } break; case TemporalMetric.REMEDIATION_LEVEL: switch (value) { case 'OF': return 'Official fix'; case 'TF': return 'Temporary fix'; case 'W': return 'Workaround'; case 'U': return 'Unavailable'; case 'ND': return 'Not Defined'; } break; case TemporalMetric.REPORT_CONFIDENCE: switch (value) { case 'UC': return 'Unconfirmed'; case 'UR': return 'Uncorroborated'; case 'C': return 'Confirmed'; case 'ND': return 'Not Defined'; } break; case EnvironmentalMetric.COLLATERAL_DAMAGE_POTENTIAL: switch (value) { case 'N': return 'None'; case 'L': return 'Low (light loss)'; case 'LM': return 'Low-Medium'; case 'MH': return 'Medium-High'; case 'H': return 'High (catastrophic loss)'; case 'ND': return 'Not Defined'; } break; case EnvironmentalMetric.TARGET_DISTRIBUTION: switch (value) { case 'N': return 'None [0%]'; case 'L': return 'Low [0-25%]'; case 'M': return 'Medium [26-75%]'; case 'H': return 'High [76-100%]'; case 'ND': return 'Not Defined'; } break; case EnvironmentalMetric.CONFIDENTIALITY_REQUIREMENT: case EnvironmentalMetric.INTEGRITY_REQUIREMENT: case EnvironmentalMetric.AVAILABILITY_REQUIREMENT: switch (value) { case 'L': return 'Low'; case 'M': return 'Medium'; case 'H': return 'High'; case 'ND': return 'Not Defined'; } break; } return 'Unknown'; }; const validateVersion$2 = (versionStr) => { if (!versionStr) { throw new Error('Invalid CVSS string. Example: CVSS:2.0/AV:N/AC:L/Au:N/C:N/I:N/A:C'); } if (versionStr !== '2.0') { throw new Error(`Unsupported CVSS version: ${versionStr}. Only 2.0 is supported by this validator.`); } }; const validate$2 = (cvssStr) => validateByKnownMaps(cvssStr, validateVersion$2, { base: baseMetrics, temporal: temporalMetrics, environmental: environmentalMetrics }, { ...baseMetricValues, ...temporalMetricValues, ...environmentalMetricValues }, { humanizeMetric: humanizeMetric$1, humanizeMetricValue: humanizeMetricValue$1 }); // eslint-disable-next-line complexity const humanizeMetric = (metric) => { switch (metric) { case BaseMetric$1.ATTACK_VECTOR: return 'Attack Vector'; case BaseMetric$1.ATTACK_COMPLEXITY: return 'Attack Complexity'; case BaseMetric$1.PRIVILEGES_REQUIRED: return 'Privileges Required'; case BaseMetric$1.USER_INTERACTION: return 'User Interaction'; case BaseMetric$1.SCOPE: return 'Scope'; case BaseMetric$1.CONFIDENTIALITY: return 'Confidentiality'; case BaseMetric$1.INTEGRITY: return 'Integrity'; case BaseMetric$1.AVAILABILITY: return 'Availability'; case TemporalMetric$1.EXPLOIT_CODE_MATURITY: return 'Exploit Code Maturity'; case TemporalMetric$1.REMEDIATION_LEVEL: return 'Remediation Level'; case TemporalMetric$1.REPORT_CONFIDENCE: return 'Report Confidence'; case EnvironmentalMetric$1.CONFIDENTIALITY_REQUIREMENT: return 'Confidentiality Requirement'; case EnvironmentalMetric$1.INTEGRITY_REQUIREMENT: return 'Integrity Requirement'; case EnvironmentalMetric$1.AVAILABILITY_REQUIREMENT: return 'Availability Requirement'; case EnvironmentalMetric$1.MODIFIED_ATTACK_VECTOR: return 'Modified Attack Vector'; case EnvironmentalMetric$1.MODIFIED_ATTACK_COMPLEXITY: return 'Modified Attack Complexity'; case EnvironmentalMetric$1.MODIFIED_PRIVILEGES_REQUIRED: return 'Modified Privileges Required'; case EnvironmentalMetric$1.MODIFIED_USER_INTERACTION: return 'Modified User Interaction'; case EnvironmentalMetric$1.MODIFIED_SCOPE: return 'Modified Scope'; case EnvironmentalMetric$1.MODIFIED_CONFIDENTIALITY: return 'Modified Confidentiality'; case EnvironmentalMetric$1.MODIFIED_INTEGRITY: return 'Modified Integrity'; case EnvironmentalMetric$1.MODIFIED_AVAILABILITY: return 'Modified Availability'; default: return 'Unknown'; } }; // eslint-disable-next-line complexity const humanizeMetricValue = (value, metric) => { switch (metric) { case BaseMetric$1.ATTACK_VECTOR: switch (value) { case 'N': return 'Network'; case 'A': return 'Adjacent'; case 'L': return 'Local'; case 'P': return 'Physical'; } break; case BaseMetric$1.ATTACK_COMPLEXITY: switch (value) { case 'L': return 'Low'; case 'H': return 'High'; } break; case BaseMetric$1.PRIVILEGES_REQUIRED: switch (value) { case 'N': return 'None'; case 'L': return 'Low'; case 'H': return 'High'; } break; case BaseMetric$1.USER_INTERACTION: switch (value) { case 'N': return 'None'; case 'R': return 'Required'; } break; case BaseMetric$1.SCOPE: switch (value) { case 'U': return 'Unchanged'; case 'C': return 'Changed'; } break; case BaseMetric$1.CONFIDENTIALITY: case BaseMetric$1.INTEGRITY: case BaseMetric$1.AVAILABILITY: switch (value) { case 'N': return 'None'; case 'L': return 'Low'; case 'H': return 'High'; } break; case TemporalMetric$1.EXPLOIT_CODE_MATURITY: switch (value) { case 'X': return 'Not Defined'; case 'U': return 'Unproven'; case 'P': return 'Proof-of-Concept'; case 'F': return 'Functional'; case 'H': return 'High'; } break; case TemporalMetric$1.REMEDIATION_LEVEL: switch (value) { case 'X': return 'Not Defined'; case 'O': return 'Official Fix'; case 'T': return 'Temporary Fix'; case 'W': return 'Workaround'; case 'U': return 'Unavailable'; } break; case TemporalMetric$1.REPORT_CONFIDENCE: switch (value) { case 'X': return 'Not Defined'; case 'U': return 'Unknown'; case 'R': return 'Reasonable'; case 'C': return 'Confirmed'; } break; case EnvironmentalMetric$1.CONFIDENTIALITY_REQUIREMENT: case EnvironmentalMetric$1.INTEGRITY_REQUIREMENT: case EnvironmentalMetric$1.AVAILABILITY_REQUIREMENT: switch (value) { case 'X': return 'Not Defined'; case 'L': return 'Low'; case 'M': return 'Medium'; case 'H': return 'High'; } break; case EnvironmentalMetric$1.MODIFIED_ATTACK_VECTOR: switch (value) { case 'X': return 'Not Defined'; case 'N': return 'Network'; case 'A': return 'Adjacent Network'; case 'L': return 'Local'; case 'P': return 'Physical'; } break; case EnvironmentalMetric$1.MODIFIED_ATTACK_COMPLEXITY: switch (value) { case 'X': return 'Not Defined'; case 'L': return 'Low'; case 'H': return 'High'; } break; case EnvironmentalMetric$1.MODIFIED_PRIVILEGES_REQUIRED: switch (value) { case 'X': return 'Not Defined'; case 'N': return 'None'; case 'L': return 'Low'; case 'H': return 'High'; } break; case EnvironmentalMetric$1.MODIFIED_USER_INTERACTION: switch (value) { case 'X': return 'Not Defined'; case 'N': return 'None'; case 'R': return 'Required'; } break; case EnvironmentalMetric$1.MODIFIED_SCOPE: switch (value) { case 'X': return 'Not Defined'; case 'U': return 'Unchanged'; case 'C': return 'Changed'; } break; case EnvironmentalMetric$1.MODIFIED_CONFIDENTIALITY: case EnvironmentalMetric$1.MODIFIED_INTEGRITY: case EnvironmentalMetric$1.MODIFIED_AVAILABILITY: switch (value) { case 'X': return 'Not Defined'; case 'N': return 'None'; case 'L': return 'Low'; case 'H': return 'High'; } break; } return 'Unknown'; }; // legacy, before introduction of Temporal and Environmental metrics support const humanizeBaseMetric = (metric) => humanizeMetric(metric); // legacy, before introduction of Temporal and Environmental metrics support const humanizeBaseMetricValue = (value, metric) => humanizeMetricValue(value, metric); const validateVersion$1 = (versionStr) => { if (!versionStr) { throw new Error('Invalid CVSS string. Example: CVSS:3.0/AV:A/AC:H/PR:H/UI:R/S:U/C:N/I:N/A:L'); } if (versionStr !== '3.0' && versionStr !== '3.1') { throw new Error(`Unsupported CVSS version: ${versionStr}. Only 3.0 and 3.1 are supported by this validator.`); } }; const validate$1 = (cvssStr) => validateByKnownMaps(cvssStr, validateVersion$1, { base: baseMetrics$1, temporal: temporalMetrics$1, environmental: environmentalMetrics$1 }, { ...baseMetricValues$1, ...temporalMetricValues$1, ...environmentalMetricValues$1 }, { humanizeMetric, humanizeMetricValue }); const validate = (cvssString) => { if (!cvssString || !cvssString.startsWith('CVSS:')) { throw new Error('CVSS vector must start with "CVSS:"'); } const versionStr = parseVersion(cvssString); const validateString = versionStr === '2.0' ? validate$2 : validate$1; validateString(cvssString); }; function calculateCvss(cvssString) { const version = parseVersion(cvssString); if (!version) { throw new Error('Invalid CVSS string: unable to detect version'); } validate(cvssString); return createCvssCalculator(version).calculate(cvssString); } /** * Calculate the base score for a CVSS string * @param cvssString - The CVSS vector string * @returns The base score (0-10) */ const calculateBaseScore = (cvssString) => calculateCvss(cvssString).baseScore; /** * Calculate the temporal score for a CVSS string * @param cvssString - The CVSS vector string * @returns The temporal score (0-10) */ const calculateTemporalScore = (cvssString) => { var _a; const res = calculateCvss(cvssString); return (_a = res.temporalScore) !== null && _a !== void 0 ? _a : res.baseScore; }; /** * Calculate the environmental score for a CVSS string * @param cvssString - The CVSS vector string * @returns The environmental score (0-10) */ const calculateEnvironmentalScore = (cvssString) => { var _a, _b; const res = calculateCvss(cvssString); return (_b = (_a = res.environmentalScore) !== null && _a !== void 0 ? _a : res.temporalScore) !== null && _b !== void 0 ? _b : res.baseScore; }; /** * Calculate base score with impact and exploitability * @param cvssString - The CVSS vector string * @returns Score result with impact and exploitability */ const calculateBaseResult = (cvssString) => { const res = calculateCvss(cvssString); return { score: res.baseScore, impact: res.baseImpact, exploitability: res.baseExploitability, metricsMap: res.metrics }; }; /** * Calculate temporal score with impact and exploitability * @param cvssString - The CVSS vector string * @returns Score result with impact and exploitability */ const calculateTemporalResult = (cvssString) => { var _a; const res = calculateCvss(cvssString); return { score: (_a = res.temporalScore) !== null && _a !== void 0 ? _a : res.baseScore, impact: res.baseImpact, exploitability: res.baseExploitability, metricsMap: res.metrics }; }; /** * Calculate environmental score with impact and exploitability * @param cvssString - The CVSS vector string * @returns Score result with impact and exploitability */ const calculateEnvironmentalResult = (cvssString) => { var _a, _b, _c, _d; const res = calculateCvss(cvssString); return { score: (_b = (_a = res.environmentalScore) !== null && _a !== void 0 ? _a : res.temporalScore) !== null && _b !== void 0 ? _b : res.baseScore, impact: res.version === '2.0' ? res.baseImpact : (_c = res.modifiedImpact) !== null && _c !== void 0 ? _c : res.baseImpact, exploitability: res.version === '2.0' ? res.baseExploitability : (_d = res.modifiedExploitability) !== null && _d !== void 0 ? _d : res.baseExploitability, metricsMap: res.metrics }; }; const parseMetricsAsMap = (cvssStr) => parseMetricsAsMap$1(cvssStr); const validateVersion = (versionStr) => { if (!versionStr) { throw new Error('Invalid CVSS string. Example: CVSS:3.0/AV:A/AC:H/PR:H/UI:R/S:U/C:N/I:N/A:L'); } if (versionStr !== '2.0' && versionStr !== '3.0' && versionStr !== '3.1') { throw new Error(`Unsupported CVSS version: ${versionStr}. Only 2.0, 3.0 and 3.1 are supported.`); } }; /** * Stringify a score into a qualitative severity rating string * @param score */ const humanizeScore = (score) => score <= 0 ? 'None' : score <= 3.9 ? 'Low' : score <= 6.9 ? 'Medium' : score <= 8.9 ? 'High' : 'Critical'; export { BaseMetric$1 as BaseMetric, EnvironmentalMetric$1 as EnvironmentalMetric, Tempor