🔢 Sort CVSS vectors by severity
Problem
You have a list of CVSS vectors and want them ordered by score — worst first for triage, or best first for a clean-up report.
Solution
Here's the flow:
CLI: sort
Given vectors.txt (one vector per line), sort defaults to descending (highest score first):
bash
cvss sort vectors.txttext
10.0 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
9.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
9.8 CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
5.3 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
3.8 CVSS:3.1/AV:L/AC:H/PR:H/UI:R/S:U/C:L/I:L/A:L
0.0 CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:U/C:N/I:N/A:NFor ascending order (lowest first), pass --asc:
bash
cvss sort --asc vectors.txttext
0.0 CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:U/C:N/I:N/A:N
3.8 CVSS:3.1/AV:L/AC:H/PR:H/UI:R/S:U/C:L/I:L/A:L
5.3 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
9.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
9.8 CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
10.0 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:Hsort also reads stdin with -:
bash
cat vectors.txt | cvss sort -Go SDK: Cvss3xSlice
cvss.NewCvss3xSlice precomputes each vector's score and implements sort.Interface. The default is descending; call .Asc() before .Sort() for ascending.
go
package main
import (
"fmt"
"github.com/scagogogo/cvss-skills/pkg/cvss"
)
func main() {
v1 := cvss.CriticalV31() // 10.0, S:C
v2 := cvss.HighV31() // 9.8, S:U
v3 := cvss.LowV31() // 3.7
// Descending — Critical first (the default).
desc := cvss.NewCvss3xSlice(v1, v2, v3).Sort()
for i, cv := range desc.Items() {
fmt.Printf("#%d %.1f %s\n", i+1, desc.ScoreAt(i), cv.String())
}
// Ascending — lowest first.
_ = cvss.NewCvss3xSlice(v1, v2, v3).Asc().Sort()
}Output of the descending loop:
text
#1 10.0 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
#2 9.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
#3 3.7 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:NScoreAt(i) returns the cached score, so reading scores after sorting is free — no re-calculation.
Discussion
- Tie-breaking is not stable by default. Two vectors scoring 9.8 keep their input order only if you sort with
sort.Stable(slice)instead ofslice.Sort()(which usessort.Sort). The CLIsortis not stable, so equal-score vectors may appear in any order. - Invalid vectors sort to score −1.
NewCvss3xSlicerecords-1for items that failCalculate, so in descending order they land at the top (−1 > nothing else) — guard withif slice.ScoreAt(i) < 0 { continue }if your input may contain incomplete vectors. - Scores are cached at construction. Mutating a vector after building the slice leaves its cached score stale; rebuild the slice if the underlying vectors change.
- Not what you want? For filtering rather than sorting, see Filter Critical vulns. For persisting sorted results to a database, see Store in a database.
See Also
sort— the CLI command- SQL & Sorting —
Cvss3xSliceAPI reference - Filter Critical vulns
- Store in a database