Expand description
CVSS v2, v3, and v4 vector string parser and score calculator.
This crate includes:
- Three CVSS version-specific modules for parsing and scoring vector strings.
- A high-level API which abstracts over version-specific parsing and scoring differences.
§Basic Use
Parse a vector string:
use polycvss::Vector;
let s = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"; // vector string
let vec: Vector = s.parse()?; // parse vector stringCalculate vector score:
use polycvss::{Score, Vector};
let s = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"; // vector string
let vec: Vector = s.parse()?; // parse vector string
let score = Score::from(vec); // get vector scoreGet score severity:
use polycvss::{Score, Severity};
let score = Score::from(9.3); // create score
let severity = Severity::from(score); // get severityVectors, scores, and severities are very small (see “Internal Representation”):
use polycvss::{Score, Severity, Vector};
assert_eq!(size_of::<Score>(), size_of::<u8>()); // 1 byte
assert_eq!(size_of::<Severity>(), size_of::<u8>()); // 1 byte
assert_eq!(size_of::<Vector>(), size_of::<u64>()); // 8 bytes§Examples
Parse vector strings:
use polycvss::Vector;
// parse CVSS v2 vector string
let v2: Vector = "AV:N/AC:L/Au:N/C:C/I:C/A:C".parse()?;
// parse CVSS v3 vector string
let v3: Vector = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H".parse()?;
// parse CVSS v4 vector string
let v4: Vector = "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H".parse()?;Get vector score:
use polycvss::{Score, Vector};
let s = "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H"; // v4 vector string
let v: Vector = s.parse()?; // parse vector string
let score = Score::from(v); // get score
assert_eq!(score, Score::from(10.0)); // check resultCompare scores:
use polycvss::Score;
let a = Score::from(1.2); // first score
let b = Score::from(3.5); // second score
assert!(a < b); // compare scoresGet score severity:
use polycvss::{Score, Severity};
let severity = Severity::from(Score::from(2.3)); // get severity
assert_eq!(severity, Severity::Low); // check resultCompare severities:
use polycvss::Severity;
let a = Severity::Low; // first severity
let b = Severity::High; // second severity
assert!(a < b); // compare severitiesGet metric from vector by name:
use polycvss::{Metric, Name, Vector, v4};
// parse CVSS v4 vector string
let v: Vector = "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H".parse()?;
// get metric
let metric = v.get(Name::V4(v4::Name::AttackVector))?;
// check result
assert_eq!(metric, Metric::V4(v4::Metric::AttackVector(v4::AttackVector::Network)));Iterate over vector metrics:
use polycvss::Vector;
// parse CVSS v4 vector string
let v: Vector = "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H".parse()?;
// print metrics
for m in v {
println!("metric: {m}");
}Convert a version-agnostic vector to a version-specific vector to access version-specific behavior:
use polycvss::{Vector, v4};
// parse CVSS v4 vector string
let v: Vector = "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H".parse()?;
// convert version-agnosic vector to a v4 vector
let v = v4::Vector::from(v);
// get nomenclature
assert_eq!(v4::Nomenclature::from(v), v4::Nomenclature::CvssB);Show that metrics are always sorted in specification order when
converting a Vector to a string. In other words, the original
metric order is not preserved:
use polycvss::Vector;
// parse v3 vector string with PR metric BEFORE AV and AC metric
let v: Vector = "CVSS:3.1/PR:N/AV:N/AC:L/UI:N/S:U/C:H/I:H/A:H".parse()?;
// check result; output string has PR metric AFTER AV and AC metric
assert_eq!(v.to_string(), "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H");Show that metrics with a value of Not Defined (X) are omitted when
converting a Vector to a string:
use polycvss::Vector;
// parse v3 vector string with MAV:X metric
let v: Vector = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/MAV:X".parse()?;
// check result; output string does NOT include MAV:X
assert_eq!(v.to_string(), "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H");§Internal Representation
A Vector is represented internally as a bit field
within a u64. Metric values are packed in the lower 60 bits
and the CVSS version is packed in the in the upper 4 bits:
| Bit Range | Description |
|---|---|
0..60 | Metric values |
60..64 | CVSS version |
The bit packing varies by CVSS version:
| Version | Module | Metric Bits | Unused Bits | Version Bits |
|---|---|---|---|---|
| CVSS v2 | polycvss::v2 | 0..32 | 32..60 | 60..64 |
| CVSS v3 | polycvss::v3 | 0..44 | 44..60 | 60..64 |
| CVSS v4 | polycvss::v4 | 0..59 | 59..60 | 60..64 |
See v2::Vector, v3::Vector, and v4::Vector for additional details.