Skip to content

Add CVSS database type

Brian Williams requested to merge bwill/add-cvss-vector-database-type into master

What does this MR do and why?

Allows for CVSS scores to be serialized to the database as CVSS vector strings, and deserialized as a CvssSuite::Cvss. This MR is a refactor and should not change any existing behavior.

This change will make it easier to implement #218601 (closed).

What is a CVSS vector?

CVSS stands for Common Vulnerability Scoring System. It's a common framework for assigning a severity to a security vulnerability. A CVSS score is composed of several parameters (anywhere from 8 to 22). Those parameters can be expressed as a single string, which is called a CVSS vector string. When storing CVSS scores in the DB, we store them as a vector string inside a text column.

Here is an attempt to illustrate:

[8] pry(main)> cvss = CvssSuite.new('CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N')
[9] pry(main)> cvss.base_score
=> 9.1
[10] pry(main)> cvss.severity
=> "Critical"
[11] pry(main)> cvss.vector
=> "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N"

Scores are typically provided as a vector string, and then used to calculate a severity level based on a formula defined by the specification. Retaining the parameters used to calculate the score is important, which is why we store the vector rather than the score or severity.

Steps to setup and validate locally

[9] pry(main)> advisory = PackageMetadata::Advisory.new(
  advisory_xid: 'mitre',
  source_xid: :glad,
  title: 'vulnerability title',
  cvss_v3: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N',
  published_date: Date.current,
  identifiers: [{type: 'CVE', name: 'CVE-2019-3888', value: 'CVE-2019-3888'}])

[10] pry(main)> advisory.save! # Note how SQL inserts vector string.
  TRANSACTION (0.3ms)  BEGIN /*application:console,db_config_name:main,console_hostname:caladan.lan,console_username:bwilliams,line:(pry):16:in `__pry__'*/
  PackageMetadata::Advisory Create (4.8ms)  INSERT INTO "pm_advisories" ("advisory_xid", "published_date", "created_at", "updated_at", "source_xid", "title", "cvss_v3", "identifiers") VALUES ('mitre', '2023-08-08', '2023-08-08 16:34:57.331062', '2023-08-08 16:34:57.331062', 1, 'vulnerability title', 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N', '[{"type":"CVE","name":"CVE-2019-3888","value":"CVE-2019-3888"}]') RETURNING "id" /*application:console,db_config_name:main,console_hostname:caladan.lan,console_username:bwilliams,line:(pry):16:in `__pry__'*/
  TRANSACTION (0.1ms)  COMMIT /*application:console,db_config_name:main,console_hostname:caladan.lan,console_username:bwilliams,line:/lib/gitlab/database.rb:418:in `commit'*/
=> true
[11] pry(main)> advisory.cvss_v3
=> #<CvssSuite::Cvss31:0x0000000289a4fea8

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Brian Williams

Merge request reports