fleet/tools/vex-parser/vex-parser.go
Lucas Manuel Rodriguez bfe3b186d3
Fix detected CVEs and docker scout exit code to fail the Github Action (#28836)
For #28837.

Fixing this all of this because we got multiple reports from the
community and customers and these were also detected by Amazon
Inspector.

- Fixes CVE-2025-22871 by upgrading Go from 1.24.1 to 1.24.2.
- `docker scout` now fails the daily scheduled action if there are
CRITICAL,HIGH CVEs (we missed setting `exit-code: true`).
- Report CVE-2025-46569 as not affected by it because of our use of
OPA's go package.
- Report CVE-2024-8260 as not affected by it because Fleet doesn't run
on Windows.
- The `security/status.md` shows a lot of changes because we are now
sorting CVEs so that newest come first.

---

- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/Committing-Changes.md#changes-files)
for more information.
- [ ] Manual QA for all new/changed functionality
- For Orbit and Fleet Desktop changes:
- [ ] Make sure fleetd is compatible with the latest released version of
Fleet (see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/fleetd-development-and-release-strategy.md)).
- [ ] Orbit runs on macOS, Linux and Windows. Check if the orbit
feature/bugfix should only apply to one platform (`runtime.GOOS`).
- [ ] Manual QA must be performed in the three main OSs, macOS, Windows
and Linux.
- [ ] Auto-update manual QA, from released version of component to new
version (see [tools/tuf/test](../tools/tuf/test/README.md)).
- [ ] For unreleased bug fixes in a release candidate, confirmed that
the fix is not expected to adversely impact load test results or alerted
the release DRI if additional load testing is needed.
2025-05-06 13:35:27 -03:00

106 lines
2.5 KiB
Go

package main
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"sort"
"strings"
)
type OpenVEXDocument struct {
Context string `json:"context"`
Statements []Statement `json:"statements"`
Author string `json:"author"`
}
type Statement struct {
Vulnerability Vulnerability `json:"vulnerability"`
Status string `json:"status"`
StatusNotes string `json:"status_notes"`
Products []Product `json:"products"`
Justification string `json:"justification,omitempty"`
Timestamp string `json:"timestamp,omitempty"`
}
type Vulnerability struct {
Name string `json:"name"`
}
type Product struct {
ID string `json:"@id"`
}
func parseOpenVEX(filePath string) (*OpenVEXDocument, error) {
data, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
var vex OpenVEXDocument
err = json.Unmarshal(data, &vex)
if err != nil {
return nil, err
}
return &vex, nil
}
func generateMarkdown(vex *OpenVEXDocument) string {
var sb strings.Builder
for _, stmt := range vex.Statements {
sb.WriteString(fmt.Sprintf("### %s\n", stmt.Vulnerability.Name))
sb.WriteString(fmt.Sprintf("- **Author:** %s\n", vex.Author))
sb.WriteString(fmt.Sprintf("- **Status:** `%s`\n", stmt.Status))
sb.WriteString(fmt.Sprintf("- **Status notes:** %s\n", stmt.StatusNotes))
if len(stmt.Products) > 0 {
sb.WriteString("- **Products:**\n")
for _, product := range stmt.Products {
sb.WriteString(fmt.Sprintf(" - `%s`\n", product.ID))
}
}
if stmt.Justification != "" {
sb.WriteString(fmt.Sprintf("- **Justification:** `%s`\n", stmt.Justification))
}
if stmt.Timestamp != "" {
sb.WriteString(fmt.Sprintf("- **Timestamp:** %s\n", stmt.Timestamp))
}
sb.WriteString("\n")
}
return sb.String()
}
func outputMarkdown(vexPath string) {
vex, err := parseOpenVEX(vexPath)
if err != nil {
fmt.Printf("Error parsing OpenVEX file %q: %s\n", vexPath, err)
return
}
md := generateMarkdown(vex)
fmt.Print(md)
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: go run main.go /path/to/directory/with/vex.json/files/")
return
}
vexPath := os.Args[1]
vexPaths, err := filepath.Glob(filepath.Join(vexPath, "*.vex.json"))
if err != nil {
fmt.Printf("Error processing directory %q: %v\n", vexPath, err)
}
if len(vexPaths) == 0 {
fmt.Printf("No vulnerabilities tracked at the moment.\n\n")
return
}
sort.Slice(vexPaths, func(i, j int) bool {
return vexPaths[i] > vexPaths[j]
})
for _, vexPath := range vexPaths {
outputMarkdown(vexPath)
}
}