cvss

CVSS (Common Vulnerability Scoring System) library for Erlang.

EEF Security WG projectMain BranchREUSE statusCoverage StatusOpenSSF Best PracticesOpenSSF BaselineOpenSSF ScorecardModule VersionTotal DownloadLicenseLast Updated

Supports all CVSS versions:

Setup

Minimum supported Erlang/OTP version is OTP 26.

Erlang

Add cvss to your dependencies in rebar.config:

{deps, [cvss]}.

Elixir

Add cvss to your dependencies in mix.exs:

{:cvss, "~> 0.1"}

Usage

Version-Agnostic API

Use the cvss module when the version is not known ahead of time:

Erlang

%% Parse a vector of any version
{ok, Cvss} = cvss:parse(<<"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H">>).

%% Calculate the overall score
9.8 = cvss:score(Cvss).

%% Get the severity rating (v3.0+)
critical = cvss:rating(Cvss).

%% Compose back to a vector string
<<"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H">> = iolist_to_binary(cvss:compose(Cvss)).

%% Check if a vector is valid
true = cvss:valid(<<"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H">>).

Elixir

# Parse a vector of any version
{:ok, cvss} = :cvss.parse("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H")

# Calculate the overall score
9.8 = :cvss.score(cvss)

# Get the severity rating (v3.0+)
:critical = :cvss.rating(cvss)

# Compose back to a vector string
"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" =
  :cvss.compose(cvss) |> IO.iodata_to_binary()

# Check if a vector is valid
true = :cvss.valid("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H")

Version-Specific Modules

For direct access to version-specific features and detailed score types, use :cvss_v1, :cvss_v2, :cvss_v3, or :cvss_v4 directly.

CVSS 1.0 / 2.0 / 3.x

These versions share the same score types: Base, Temporal, and Environmental. Each score builds on the previous one.

Erlang

{ok, Cvss} = cvss_v3:parse(<<"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/E:F/RL:W/RC:R">>).

9.8 = cvss_v3:base_score(Cvss).
9.1 = cvss_v3:temporal_score(Cvss).
9.1 = cvss_v3:environmental_score(Cvss).
9.1 = cvss_v3:score(Cvss).  %% Returns the most specific score available

Elixir

{:ok, cvss} = :cvss_v3.parse("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/E:F/RL:W/RC:R")

9.8 = :cvss_v3.base_score(cvss)
9.1 = :cvss_v3.temporal_score(cvss)
9.1 = :cvss_v3.environmental_score(cvss)
9.1 = :cvss_v3.score(cvss)  # Returns the most specific score available

CVSS 4.0

CVSS 4.0 uses a unified scoring formula. The score functions control which metric groups are considered, matching the CVSS 4.0 nomenclature:

Function Nomenclature Metrics Used
base_score/1 CVSS-B Base only
threat_score/1 CVSS-BT Base + Threat
environmental_score/1 CVSS-BE Base + Environmental
score/1 CVSS-BTE Base + Threat + Environmental

Erlang

{ok, Cvss} = cvss_v4:parse(
    <<"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/E:P">>
).

cvss_v4:base_score(Cvss).          %% CVSS-B: ignores threat & environmental
cvss_v4:threat_score(Cvss).        %% CVSS-BT: ignores environmental
cvss_v4:environmental_score(Cvss). %% CVSS-BE: ignores threat
cvss_v4:score(Cvss).               %% CVSS-BTE: uses all present metrics

Elixir

{:ok, cvss} = :cvss_v4.parse(
  "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/E:P"
)

:cvss_v4.base_score(cvss)          # CVSS-B: ignores threat & environmental
:cvss_v4.threat_score(cvss)        # CVSS-BT: ignores environmental
:cvss_v4.environmental_score(cvss) # CVSS-BE: ignores threat
:cvss_v4.score(cvss)               # CVSS-BTE: uses all present metrics

Working with Records in Elixir

The parsed CVSS values are Erlang records. To pattern match or construct them in Elixir, use Record.defrecord/2:

import Record

defrecord :cvss_v3, Record.extract(:cvss_v3, from_lib: "cvss/include/cvss_v3.hrl")
defrecord :cvss_v4, Record.extract(:cvss_v4, from_lib: "cvss/include/cvss_v4.hrl")

# Pattern match on parsed results
{:ok, cvss} = :cvss_v3.parse("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H")
cvss_v3(av: :network, c: confidentiality) = cvss

Severity Ratings

Qualitative severity ratings are defined by the CVSS v3.0, v3.1, and v4.0 specifications. The cvss:rating/1 function applies these thresholds:

Rating Score Range
none 0.0
low 0.1 – 3.9
medium 4.0 – 6.9
high 7.0 – 8.9
critical 9.0 – 10.0

CVSS v1.0 and v2.0 do not define severity ratings in their specifications. The same thresholds are applied as a convenience but are not spec-mandated for those versions.