🔁 Migrate CVSS v3.0 vectors to v3.1
Problem
Your backlog of advisories is tagged with CVSS v3.0 vectors, but your tooling now expects v3.1. You need to convert them — and know when the score changes.
Solution
Here's the flow:
CLI: convert --to 3.1
The vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H has identical metrics in both versions, so its score is unchanged:
bash
cvss convert --to 3.1 "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"text
Original: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (9.8)
Converted: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (9.8)But UI:R (User Interaction: Required) scores 0.56 in v3.0 and 0.62 in v3.1, so any vector with UI:R moves:
bash
cvss convert --to 3.1 "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H"text
Original: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H (8.5)
Converted: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H (8.8)The downgrade goes the other way (8.8 → 8.5):
bash
cvss convert --to 3.0 "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H"text
Original: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H (8.8)
Converted: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H (8.5)Go SDK: UpgradeTo31
UpgradeTo31 is sugar for ConvertToVersion(3, 1). It clones the vector and bumps the version — metric values are untouched, but the calculator uses the v3.1 weights on the result.
go
package main
import (
"fmt"
"github.com/scagogogo/cvss-skills/pkg/cvss"
"github.com/scagogogo/cvss-skills/pkg/parser"
)
func main() {
v30, _ := parser.ParseString("CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H")
v31, err := v30.UpgradeTo31()
if err != nil {
panic(err)
}
fmt.Println(v31.String()) // CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
// Downgrade is symmetric.
back, _ := v31.DowngradeTo30()
fmt.Println(back.String()) // CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
_ = cvss.NewCalculator
}ConvertToVersion only accepts 3.0 and 3.1; any other version returns unsupported version: %d.%d.
Discussion
- Only
UI:Rchanges the score. The v3.0→v3.1 spec change that affects scoring is theUI:Requiredweight (0.56 → 0.62). Vectors withUI:N(the common case) keep their exact score after conversion. - Severity band may shift. A v3.0 vector at 8.9 (High) with
UI:Rcan become 9.x (Critical) after upgrade. Always re-check the severity, not just the score, after migrating. - Metric values are not changed.
convertis a version bump, not a metric re-interpretation — if your v3.0 vector hadE:F, the v3.1 result still hasE:F. - Bulk migration. Wrap
convertin a shell loop overvectors.txt, or callUpgradeTo31in aReadCSV→WriteCSVpipeline. Score the converted vectors with Parse from CSV afterward. - Not what you want? If you're comparing a v3.0 and a v3.1 vector of the same CVE, use Compare two vectors —
diffworks across versions.
See Also
convert— the CLI command- Conversion —
ConvertToVersion/UpgradeTo31/DowngradeTo30reference - Compare two vectors
- Parse from CSV