cvss (cvss v0.1.1)

View Source

Version-agnostic API for CVSS (Common Vulnerability Scoring System).

This module handles all CVSS versions (1.0, 2.0, 3.0, 3.1, and 4.0) and automatically detects the version when parsing. Use this module when the CVSS version is not known ahead of time, for example when parsing vectors from external sources.

If you already know which version you are working with, use the version-specific module directly instead: cvss_v1, cvss_v2, cvss_v3, or cvss_v4.

Summary

Types

A CVSS score value, ranging from 0.0 (no impact) to 10.0 (critical).

Functions

Compose a CVSS record into a vector string.

Parse a CVSS vector string into a record.

Get the severity rating for a CVSS score or vector.

Calculate the CVSS score.

Check whether a CVSS value is valid.

Types

cvss()

-type cvss() :: cvss_v1:cvss() | cvss_v2:cvss() | cvss_v3:cvss() | cvss_v4:cvss().

cvss_error()

-type cvss_error() :: parse_error() | validation_error().

parse_error()

-type parse_error() ::
          {invalid_prefix, Prefix :: binary()} |
          {invalid_metric, Metric :: binary(), Value :: binary()} |
          {missing_required_metric, Metric :: atom()} |
          {duplicate_metric, Metric :: binary()} |
          malformed_vector.

score()

-nominal score() :: number().

A CVSS score value, ranging from 0.0 (no impact) to 10.0 (critical).

severity()

-type severity() :: none | low | medium | high | critical.

validation_error()

-type validation_error() ::
          {invalid_metric_value, Metric :: atom(), Value :: term()} |
          {missing_required_metric, Metric :: atom()}.

Functions

compose/1

-spec compose(cvss()) -> iolist().

Compose a CVSS record into a vector string.

> {ok, Cvss} = cvss:parse(<<"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)).
<<"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H">>

parse/1

-spec parse(iodata()) -> {ok, cvss()} | {error, parse_error()}.

Parse a CVSS vector string into a record.

Automatically detects the CVSS version from the vector format:

  • CVSS 4.0: Starts with CVSS:4.0/
  • CVSS 3.1: Starts with CVSS:3.1/
  • CVSS 3.0: Starts with CVSS:3.0/
  • CVSS 2.0: Starts with AV: and uses N/A/L for Access Vector
  • CVSS 1.0: Starts with AV: and uses R/L for Access Vector
> cvss: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">>).
{ok, #cvss_v4{av = network, ac = low, at = none, pr = none, ui = none,
              vc = high, vi = high, va = high, sc = high, si = high, sa = high}}

> cvss:parse(<<"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H">>).
{ok, #cvss_v3{version = '3.1', av = network, ac = low, pr = none,
              ui = none, s = unchanged, c = high, i = high, a = high}}

> cvss:parse(<<"AV:N/AC:L/Au:N/C:P/I:P/A:C">>).
{ok, #cvss_v2{av = network, ac = low, au = none, c = partial, i = partial, a = complete}}

> cvss:parse(<<"AV:R/AC:L/Au:NR/C:C/I:C/A:C">>).
{ok, #cvss_v1{av = remote, ac = low, au = not_required,
              c = complete, i = complete, a = complete}}

> cvss:parse(<<"CVSS:5.0/AV:N">>).
{error, {invalid_prefix, <<"CVSS:5.0/AV:N">>}}

> cvss:parse(<<"INVALID">>).
{error, malformed_vector}

rating/1

-spec rating(iodata() | cvss()) -> severity().

Get the severity rating for a CVSS score or vector.

Thresholds are the same for all CVSS versions:

  • None: 0.0
  • Low: 0.1 - 3.9
  • Medium: 4.0 - 6.9
  • High: 7.0 - 8.9
  • Critical: 9.0 - 10.0
> cvss:rating(<<"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H">>).
critical

> cvss:rating(<<"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N">>).
none

score/1

-spec score(iodata() | cvss()) -> score().

Calculate the CVSS score.

Accepts either a vector string or a parsed record. Returns the appropriate score based on which metrics are present:

  • Environmental score (if environmental metrics present)
  • Temporal score (if temporal metrics present)
  • Base score (otherwise)
> cvss:score(<<"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H">>).
9.8

> cvss:score(<<"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N">>).
0.0

> cvss:score(<<"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H">>).
10.0

valid/1

-spec valid(iodata() | cvss()) -> boolean().

Check whether a CVSS value is valid.

Accepts either a vector string or a parsed record. Returns true if valid, false otherwise.

> cvss:valid(<<"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H">>).
true

> cvss:valid(<<"INVALID">>).
false

> cvss:valid(#cvss_v3{version = '3.1', av = network, ac = low, pr = none,
                        ui = none, s = unchanged, c = high, i = high, a = high}).
true