Skip to content

pablotron/polycvss

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

polycvss

Rust library to parse and score CVSS vector strings.

Features:

  • CVSS v2, CVSS v3, and CVSS v4 support.
  • Version-agnostic parsing and scoring API.
  • Memory efficient: Vectors are 8 bytes. Scores and severities are 1 byte.
  • No dependencies by default except the standard library.
  • Optional serde integration via the serde build feature.
  • Extensive tests: Tested against thousands of vectors and scores from the NVD CVSS calculators.

Links:

Here is an example tool which parses the first command-line argument as a CVSS vector string, then prints the score and severity:

use polycvss::{Err, Score, Severity, Vector}; fn main() -> Result<(), Err> { let args: Vec<String> = std::env::args().collect(); // get cli args if args.len() == 2 { let vec: Vector = args[1].parse()?; // parse string let score = Score::from(vec); // get score let severity = Severity::from(score); // get severity println!("{score} {severity}"); // print score and severity } else { let name = args.first().map_or("app", |s| s); // get app name eprintln!("Usage: {name} [VECTOR]"); // print usage } Ok(()) }

Here is the example tool output for a CVSS v2 vector string, a CVSS v3 vector string, and a CVSS v4 vector string:

# test with cvss v2 vector string $ cvss-score "AV:A/AC:H/Au:N/C:C/I:C/A:C" 6.8 MEDIUM # test with cvss v3 vector string $ cvss-score "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" 9.8 CRITICAL # test with cvss v4 vector string $ cvss-score "CVSS:4.0/AV:L/AC:H/AT:N/PR:N/UI:P/VC:L/VI:L/VA:L/SC:H/SI:H/SA:H" 5.2 MEDIUM

This example tool is included in the Git repository as src/bin/cvss-score.rs.

Examples

Parse vector strings:

// 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:

// 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 score let score = Score::from(v); // check result assert_eq!(score, Score::from(10.0));

Compare scores:

let a = Score::from(1.2); // first score let b = Score::from(3.5); // second score assert!(a < b); // compare scores

Get score severity:

let severity = Severity::from(Score::from(2.3)); assert_eq!(severity, Severity::Low);

Compare severities:

let a = Severity::Low; // first severity let b = Severity::High; // second severity assert!(a < b); // compare severities

Get metric from vector by name:

// 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:

// 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:

// parse 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);

See the examples/ directory for more examples.

Install

polycvss package page on crates.io

Run cargo add polycvss to add polycvss as a dependency to an exiting Rust project:

$ cargo add polycvss

Run cargo install polycvss to install the example cvss-score tool:

# install cvss-score in cargo bin dir (e.g. `~/.cargo/bin`) $ cargo install polycvss

Build

Run cargo build to create a debug build of the example tool in target/debug/:

$ cargo build ... $ target/debug/cvss-score "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" 9.8 CRITICAL

Run cargo build --release to create a release build of the example tool in target/release/:

$ cargo build --release ... $ target/release/cvss-score "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" 9.8 CRITICAL

You can also build the example cvss-score tool in a container using Podman or Docker like this:

$ podman run --rm -t -v "$PWD":/src -w /src docker.io/rust cargo build --release ... $ target/release/cvss-score "CVSS:4.0/AV:L/AC:H/AT:N/PR:N/UI:P/VC:L/VI:L/VA:L/SC:H/SI:H/SA:H" 5.2 MEDIUM

To build a static binary of the example cvss-score tool in a container:

$ podman run --rm -it -v .:/src -w /src rust sh -c "rustup target add $(arch)-unknown-linux-musl && cargo build --release --target $(arch)-unknown-linux-musl" ... $ ldd target/$(arch)-unknown-linux-musl/release/cvss-score statically linked $ du -sh target/$(arch)-unknown-linux-musl/release/cvss-score 604K target/x86_64-unknown-linux-musl/release/cvss-score

Documentation

polycvss API documentation on docs.rs

Run cargo doc to build the API documentation locally in target/doc/polycvss/:

$ cargo doc ... $ ls target/doc/polycvss/index.html target/doc/polycvss/index.html

Run cargo doc --lib build the library documentation and exclude the example tool documentation:

# remove generated docs # (needed to clean up stale artifacts) $ cargo clean --doc # generate library-only docs $ cargo doc --lib

Tests

Use cargo test to run the test suite:

$ cargo test ... test result: ok. 369 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s $

Use cargo clippy to run the linter:

$ cargo clippy Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s $

The test suite includes a large number of scored CVSS vector string test cases. The test cases were generated using cvss-calcs.

The generated test cases can be found in src/v3.rs, src/v3.rs, and src/v4.rs.

About

CVSS v2, v3, and v4 vector string parser and score calculator.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages